synchronized修饰几种不同情况的具体用法
synchronized method 锁定当前new的对象
static method 所有对象 class锁
代码块 当前new对象
当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
修饰方法时候:
即一次只能有一个线程进入该对象的方法,其他线程要想在此时调用该方法,只能排队等候.
public synchronized void test() {
//方法体
}
2.修饰代码块的时候
线程可以进入该对象的方法,但是被synchronized修饰的代码块不能被多个线程同时进入该对象的这个方法,但是代码块之外的代码可以被访问。
public int test(int a){
synchronized(a) {
//一次只能有一个线程进入
}
}
3.修饰对象的时候
对象与对象之间是互不干扰的,不同对象可以同时进行,但是只有一个对象,多个线程时候,会形成互斥,只有一个执行完了另一个才能执行。
如果修饰特定对象时候,谁拥有这个对象的锁,谁就可以运行被锁这的这个代码块。
public void run() {
synchronized (this) {
//对象锁
}
}
4.修饰类的时候
当需要对有static修饰的时候,使用类来解决同步问题。
静态方法是属于类的而不属于对象的,synchronized修饰的静态方法锁定的是这个类的所有对象
public void test(){
synchronized(Test.class);
//如果线程进入,则线程在该类中所有操作不能进行,包括静态变量和静态方法
}
总结:
A. 无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。
B. 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。
C. 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
参考资料:http://blog.youkuaiyun.com/luoweifu/article/details/46613015