据我所知,当类中有多个同步方法(包括静态方法和实例方法)时,java只允许一次运行一个这样的方法。但是,如果线程获取对象实例(或类)上的锁,然后在该对象内输入一个同步方法,然后调用同一个对象的另一个同步方法,又会怎样呢?我的意思是:
Class AA
{
..
..
synchronized void X()
{
Y();
}
synchronized void Y()
{
..
..
} 是否有任何线程退出方法X将永远阻塞?既然java不允许同时运行方法X和Y?
发布于 2015-06-10 12:11:57
在Java中,synchronized锁是重入者。
换句话说,如果您的线程已经持有对象的锁,则不必等待它自己。
发布于 2015-06-10 12:18:08
如果仔细阅读synchronized的文档,您会发现,一旦线程获得了锁,就可以根据需要重新获取它。
根据Java语言规范:
第8.4.3.6节。“同步方法”表示synchronized关键字获得一个监视器。请参阅:http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.6
然后,"17.1同步“部分指出线程t可以多次锁定特定监视器。请参阅http://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.1
因此,只有其他线程才需要等待,如果线程已经获得了锁。相同的线程可以重新获得锁,而无需等待。
发布于 2015-06-10 12:54:28
Java同步对同步方法的实例使用递归锁。就好像每个实例都有一个递归锁一样,@同步将锁定这个递归锁(JVM显然使用了一种更聪明的方法)。因此:
对于@同步类方法,对类本身使用递归锁。同样的规则也适用于上面,因为类是第一类对象。
java一次只允许运行一个这样的方法。
那绝对不是真的。首先,10个线程可以调用10个不同实例的10个同步方法,并且它们都可以在第一次运行。每个同步方法都可以依次调用其他实例的其他同步方法,只要它们不与@同步方法一起使用,这也将有效。而且每个@同步方法都可以递归地调用同一个实例的@同步方法,只要它愿意。
限制是:没有两个线程可以同时运行同一个实例的@同步方法,也不能同时运行同一个类的@同步类方法。
https://softwareengineering.stackexchange.com/questions/286374
复制相似问题