-
答案 1:
要明白两个问题,1.锁的对象是谁,2.谁持有了锁。假设方法A和B是在同一个类Test中的两个方法。Test t=new Test();t.methodB();这个时候,methodB方法被调用时,因为加了synchronized ,需要先获得一个锁,这个锁的对象应该是t,也就是当前的这个Test类的实例,而获得锁的东西是线程,也就是说当前线程拿到了t的锁(而不是你说的B方法获得锁),这个时候B方法内调用methodA,因为A也加了synchronized,也需要获得一个锁,因为A和B都是Test类中的方法,所以当前线程要获得的锁的对象也是t。由于当前线程在执行B方法时已经持有了t对象的锁,因此这时候调用methodA是没有任何影响的,相当于方法A上没有加synchronized。另一种情况:假设现在有两个Test类Test t1=new Test();Test t2=new Test();t1.methodB();//此时当前线程持有了t1对象的锁t2.methodB();//此时当前线程也持有了t2对象的锁当前线程持有了两把锁,锁的对象分别是两个不同的Test类的实例t1和t2,互相没有影响。再一种情况:假设在多线程环境下,两个线程都可以访问Test t=new Test();此时假设thread1里调用t.methodB();同时thread2里调用t.methodB()这时假设thread1先抢到t对象的锁,那么thread2需要等待thread1释放t对象的锁才可以执行B方法。结果像这样:thread1获得t的锁--thread1执行methodB--thread1执行methodA--释放t的锁---thread2获得t的锁--thread2执行methodB--thread2执行methodA--释放t的锁。synchronized还有很多种使用方法,但只有明白是那条线程获得哪个对象的锁,就很容易明白了。 -
答案 2:
加在非static方法上的synchronized方法是和synchronized(this)块等价的,均为对象锁,即对this加锁。获得当前对象锁的线程,可以继续获得当前对象锁,JVM负责跟踪对象被加锁的次数。线程运行B方法,此时如果this锁可以用,线程获得该锁,线程给对象加锁,计数器变成1,然后B方法调用A方法,由于是对同一个对象同一个线程,线程可以继续获得锁,计数器变为2,表示this被加锁2次。A方法完毕后,线程释放锁,计数器变为1,此时对象锁对其他线程依然是不可获得的。B方法完毕后,线程继续释放锁,此时计数器变为0,表示锁被完全释放,其他线程可以获得对象锁。 -
答案 3:
可以,一个线程对同一个对象的锁可以反复获取。这种同步锁称为可重入的锁。 -
答案 4:
synchronized 锁机制存在重入的特性,就是可以重复获取同一个对象的锁 -
答案 5:
methodA试图在上面获得锁的对象如果就是methodB所锁住的那个对象,那就可以吧 -
答案 6:
写在方法上的synchronized,锁的对象是this进入一次,计数器+1,离开,计数器-1 -
答案 7:
锁的基本机制 @beralee将的很清楚;@孙立伟讲了反复获取锁。反复获取锁是有意义的。@邓梁 同学补充了较详细的正常流程的解除嵌套锁的计数器实现。我稍微补充一句:与之相对的问题还有,方法抛出异常时,线程足够聪明以释放所有反复获取到到的锁。详情可以参考官方的虚拟机规范。 -
答案 8:
只要明白两个问题就好了。1:谁获取了锁。2:获取了谁的锁。
java synchronized同步方法调用另一个同步方法,锁机制问题
2012-01-19 19:53:39 来源: 点击:
相关热词搜索:
上一篇:普洱茶现在都有哪些高端品牌?
下一篇:有自己的上半身照片,如何制作自己的漫画头像?