我在Java中有这个代码:
public void doSomeThing() {
synchronized (this) {
doSomeThingElse();
}
}
public void doSomeThingElse() {
synchronized (this) {
// do something else
}
}
此代码可以阻止吗?我的意思是,这段代码可以等待吗?
答案 0 :(得分:49)
作为可重入锁定的java documentation describes :
线程可以获取它的锁 已经拥有
第二个同步块使用相同的锁,因此总是可以使用,因为已经在外部方法中获取了锁。
不,不会出现僵局。
答案 1 :(得分:8)
如果一个帖子拥有this
上的锁,它会进入其他synchronized
方法/块,就像黄油中的热刀一样。
答案 2 :(得分:3)
在同步块中,您可以重新获取已拥有的锁。第一个线程将获取锁定提供程序(this)以输入doSomething()。然后在doSomethingElse()方法中,它将重新获取它。
这样做的原因?好吧没有什么可说的,没有其他线程从其他地方输入doSomethingElse。这将阻止任何代码在doSomething()中执行块,直到doSomethingElse()中的线程释放“this”。
编辑 BTW它当然可以阻止...它会阻止任何不拥有同步对象的线程执行。但是它不会(如已发布)死锁。
答案 3 :(得分:1)
Lock已经被执行doSomething方法的线程所取代,因此该线程可以执行doSomethingElse方法。
您需要两个锁定对象来创建死锁情况。在您的情况下,只有一个,因此不可能创建死锁。
答案 4 :(得分:0)
this
两种情况下的同步使用,因此如果运行doSomeThing中的synchronized块,则您已经拥有了锁,因此您可以执行doSomeThingElse方法。
如果您的代码非常简单,则相当于:
public synchronized void doSomeThing() {
doSomeThingElse();
}
public synchronized void doSomeThingElse() {
// do something else
}
答案 5 :(得分:0)
您已经在第一次同步中取得了监视器锁定。 您应始终确保并发设计不会对性能产生巨大影响。
确保这一点的一种方法是仅同步所需的语句/代码。
现在假设您的代码看起来像这样。
public void doSomeThing()
{
synchronized (this)
{
synchronized (this)
{
// do something else
}
}
}
这是必需的
public void doSomeThing()
{
doSomeThingElse();
}
public void doSomeThingElse()
{
synchronized (this)
{
// do something else
}
}