关于synchronized

网友投稿 235 2022-11-27

关于synchronized

如果用synchronized修饰一个类成员方法A,那么就不会出现下面的情况: 同时多个线程访问这个类的A方法。 当然如果还有一个方法B,它没有被synchronized修饰,那么A方法与B方法是可以并行执行的。如下:

package thread;public class SyncTest implements Runnable { public synchronized void m1() throws Exception{ System.out.println("m1开始"); Thread.sleep(2000); System.out.println("m1结束"); } public void m2() throws Exception { System.out.println("m2开始"); Thread.sleep(2000); System.out.println("m2结束"); } public void run() { try { m1(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { SyncTest tt = new SyncTest(); Thread t = new Thread(tt); t.start(); Thread.sleep(1000); //保证先运行m1 tt.m2(); }}

大家可以先猜一下运行结果

m1先运行打印出

m1开始

然后睡觉(2s后醒来)

过了大概1s

tt.m2()运行了

打印出

m2开始

再等一会

m1结束

m2结束

运行的结果也确实是

m1开始

m2开始

m1结束

m2结束

我们得出一个结论

成员函数A使用synchronized修饰,并不会影响没有使用synchronized修饰的方法B。

不过如果给m2也加上synchronized,会怎么呢?

结果如下

m1开始

m1结束

m2开始

m2结束

恩?答案是的。即使我们m1休眠的时间再长,m2也不会在m1执行结束之前启动。

因而我们得出结论

如果一个类中多个成员函数都用synchronized修饰,那么即使在多线程下,这些函数也不能同时被调用。

上面说的所以函数都是成员函数,如果把synchronized加到static方法上呢?

大家都知道,static的方法属于类方法,它属于这个Class(注意:这里的Class不是指Class的某个具体对象),那么static获取到的锁,就是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。而非static方法获取到的锁,就是当前调用这个方法的对象的锁了。所以,他们之间不会产生互斥。

看下面的例子

/** * @author Jack Zhang * @version vb1.0 * @Email virgoboy2004@163.com * @Date 2012-5-20 */public class Test{ public static synchronized void staticX() throws InterruptedException { for (int i = 0; i < 10; i++){ Thread.sleep(1000); System.out.println("staticX......................."); } } public synchronized void x() throws InterruptedException{ for (int i = 0; i < 10; i++){ Thread.sleep(1000); System.out.println("x......................."); } } public static void main(String[] args) { final Test test1 = new Test(); Thread thread = new Thread(new Runnable(){ public void run(){ try{ test1.x(); }catch (InterruptedException e){ // TODO Auto-generated catch block e.printStackTrace(); } } }, "a"); Thread thread1 = new Thread(new Runnable(){ public void run(){ try{ Test.staticX(); } catch (InterruptedException e){ // TODO Auto-generated catch block e.printStackTrace(); } } }, "b"); thread1.start(); thread.start(); }}

结果是

staticX.......................

x.......................

x.......................

staticX.......................

staticX.......................

x.......................

x.......................

staticX.......................

x.......................

staticX.......................

staticX.......................

x.......................

x.......................

staticX.......................

x.......................

staticX.......................

x.......................

staticX.......................

x.......................

staticX.......................

一个锁加到的类上,另一个锁加到了对象上。是两回事。

那当我们想让所有这个类下面的对象都同步的时候,也就是让所有这个类下面的对象共用同一把锁的时候,我们如何办呢?

看代码:

/** * @author Jack Zhang * @version vb1.0 * @Email virgoboy2004@163.com * @Date 2012-5-20 */public class Test{ public final static Byte[] locks = new Byte[0]; public static void staticX() throws InterruptedException { synchronized (locks) { for (int i = 0; i < 10; i++) { Thread.sleep(1000); System.out.println("staticX......................."); } } } public void x() throws InterruptedException { synchronized (locks) { for (int i = 0; i < 10; i++) { Thread.sleep(1000); System.out.println("x......................."); } } } public static void main(String[] args) { final Test test1 = new Test(); final Test test2 = new Test(); Thread thread = new Thread(new Runnable() { public void run() { try { test1.x(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, "a"); Thread thread1 = new Thread(new Runnable() { public void run() { try { Test.staticX(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, "b"); thread1.start(); thread.start(); }}

结果

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

x.......................

x.......................

x.......................

x.......................

x.......................

x.......................

x.......................

x.......................

x.......................

x.......................

关于synchronized(this)

我们知道在java中,this指的是调用这个方法的对象

如果我们写这样的锁synchronized(this) 会怎么样呢? 试一下不就知道了

public class Test{ public final static Byte[] locks = new Byte[0]; public void staticX() throws InterruptedException { synchronized (this) { for (int i = 0; i < 10; i++) { Thread.sleep(1000); System.out.println("staticX......................."); } } } public void x() throws InterruptedException { // synchronized (this) { for (int i = 0; i < 10; i++) { Thread.sleep(1000); System.out.println("x......................."); } } } public static void main(String[] args) { final Test test1 = new Test(); // final Test test2 = new Test(); Thread thread = new Thread(new Runnable() { public void run() { try { test1.x(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, "a"); Thread thread1 = new Thread(new Runnable() { public void run() { try { test1.staticX(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, "b"); thread1.start(); thread.start(); }}

此时x与staticx交替打印

这个大家能理解吗?x()方法没有任何锁,它自然能执行

如果我去掉x()方法里面的

// synchronized (this)

这行的注释呢?

结果是先连续打印10个staticx然后再打印10个x

感谢glt

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:springboot整合springsecurity与mybatis
下一篇:KUKA机器人高级编程CWRITE的用法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~