探讨Java中static synchronized和synchronized
来源:互联网 发布:淘宝店铺主页尺寸 编辑:程序博客网 时间:2024/05/17 18:46
synchronized提供内部锁的机制,防止其它线程同时进入synchronized的代码块。synchronized由两部分组成:1.锁对象的引用;2.锁保护的代码块。
对锁对象引用的不同,是static synchronized和synchronized最大的区别:
1 public class SynchronizedTester { 2 3 /* 4 * testOne()和testTwo()均是对SynchronizedTester这个类的对象(实例)加上锁 5 * 也就是锁对象的引用是SynchronizedTester这个类的对象(实例) 6 * 两种写法基本等价 7 */ 8 private synchronized void testOne(){ 9 //do something...10 }11 private void testTwo(){12 synchronized(this){13 //do something...14 }15 }16 17 }
1 public class SynchronizedStaticTester { 2 /* 3 * testOne()和testTwo()则是对SynchronizedTester这个类加上锁 4 * 也就是锁对象的引用是SynchronizedTester这个类,不再是类的对象或类的实例 5 * 两种写法基本等价 6 */ 7 private static synchronized void testOne(){ 8 //do sth. 9 }10 11 private static void testTwo(){12 synchronized (SynchronizedStaticTester.class) { //Notice: Not this!13 // do sth.14 }15 }16 17 18 19 }
synchronized的范围是某个类的对象/实例,防止多个线程同时访问同一个类对象/实例的synchronized代码块。
static synchronized地方范围是某个类,防止多个线程同时访问这个类的synchronized代码块。
知道区别以后看看题目:
1.出自并发编程网:
1 public class A { 2 3 private static boolean isTrue; 4 5 public static synchronized void staticWrite(boolean b){ 6 isTrue = b; 7 } 8 9 public static synchronized boolean staticRead(){10 return isTrue;11 }12 13 public synchronized void write(boolean b){14 isTrue = b;15 }16 17 public synchronized boolean read(){18 return isTrue;19 }20 }
问题:
- 线程1访问A.staticWrite(true)方法时,线程2能访问A.staticRead()方法吗?
- 线程1访问new A().staticWrite(false)方法时,线程2能访问new A().staticRead()方法吗?
- 线程1访问A.staticWrite(false)方法时,线程2能访问new A().staticRead()方法吗?
答案是都不能。因为无论A创建多少个对象或实例,任一对象调用staticWrite(),或类直接调用staticWrite(),锁对象的引用都是A.class。也就是只要调用staticWrite方法,都会对A.class加锁,而staticRead()需要获得的锁对象也正是A.class,因此会出现阻塞。所以线程2无法访问A.staticRead()方法。
- A a=new A(); 线程1访问a.write(false)方法,线程2能访问a.read()方法吗?
- A a=new A(); A b=new A();线程1访问a.write(false)方法,线程2能访问b.read()方法吗?
题目1答案是不可以,理由与上面类似。a.write()对类A的对象a加了锁,而a.read()需要获得的锁对象也刚好是a,所以线程2无法访问a.read()
题目2答案是可以,a.write()对类A的对象加了锁,而b.read()需要获得的锁对象则是b,两者无冲突。b.read()能顺利获得锁,并访问read()方法。
再次总结:
- 对于实例同步方法,锁是当前实例对象。
- 对于静态同步方法,锁是当前对象的Class对象。
- 对于同步方法块,锁是Synchonized括号里配置的对象。
再看一题,出自日本作者-结成浩的《java多线程设计模式》:
1 pulbic class Something(){2 public synchronized void isSyncA(){}3 public synchronized void isSyncB(){}4 public static synchronized void cSyncA(){}5 public static synchronized void cSyncB(){}6 }
有Something类的两个实例x与y,那么下列组方法何以被1个以上线程同时访问呢
a. x.isSyncA()与x.isSyncB()
b. x.isSyncA()与y.isSyncA()
c. x.cSyncA()与y.cSyncB()
d. x.isSyncA()与Something.cSyncA()
有了上面的知识,很容易判断a,c不能,而b可以。d稍微分析一下,也可以确定可以被1个以上线程同时访问,因此x.isSyncA()锁的是Something的对象x,而Something.cSyncA()锁的是Something.class。
最后要留意的是:synchronized并不能继承,子类覆盖父类synchronized方法时,一定也要在前面加上synchronized关键字;但子类未重写该方法,实例化子类,调用对应方法,也会加锁
这篇文章对synchronized关键字做了深入的总结,值得仔细理解。
- 探讨Java中static synchronized和synchronized
- 探讨Java中static synchronized和synchronized
- Java多线程中Synchronized简介和Static Synchronized的区别
- Java多线程中Synchronized简介和Static Synchronized的区别
- Java synchronized和synchronized static详解
- Java static synchronized 和 synchronized的区别
- Synchronized和Static Synchronized区别
- Synchronized和Static Synchronized区别
- Synchronized和Static Synchronized区别
- Synchronized和Static Synchronized区别
- 深入理解Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别
- JAVA中synchronized与static synchronized 的区别
- JAVA中synchronized与static synchronized 的区别
- java中synchronized与static synchronized 的区别
- java中synchronized与static synchronized 的区别
- Java synchronized与static synchronized 的区别
- synchronized和static synchronized的比较
- Synchronized 和 static synchronized 的区别
- jQuery选择器总结
- win7无法访问Samba,解决方案
- POJ 1664 放苹果
- nginx的配置文件
- Linux下调用pthread库实现简单线程池
- 探讨Java中static synchronized和synchronized
- Linux下通用线程池的创建与使用
- HDOJ 3478 Catch
- QuickTime SDK 7.3 for Windows
- 图像处理基础之卷积
- Cocos2dx交叉编译至android平台
- ubuntu 配置kermit
- 关于 IOS 项目中出现的 Apple Mach-O Linker Error Group 的问题解决
- uva 10440 Ferry Loading II