假设我们有一个对象foo:
class Foo(){
public synchronized void instanceMethod(){}
}
var foo = new Foo();
如果我锁定foo:
synchronized(foo){
foo.instanceMethod();
}
我也锁定了instanceMethod()
通话吗?提出问题的另一种方式-如果我对foo有锁,另一个线程可以同时调用foo.instanceMethod()吗?
答案 0 :(得分:3)
如果我对foo有锁,另一个线程可以调用foo.instanceMethod()吗?
他们可以调用它,但是调用将一直等到执行离开synchronized
上的块foo
为止,因为instanceMethod
是synchronized
。声明实例方法synchronized
与将其整个主体放在synchronized
上的块this
中相同。
如果instanceMethod
不同步,则通话当然不会等待。
不过请注意,您显示的synchronized
块是不必要的:
synchronized(foo){ // <==== Unnecessary
foo.instanceMethod();
}
由于instanceMethod
是synchronized
,因此可能是:
foo.instanceMethod();
...除非块中也有其他东西。
答案 1 :(得分:2)
class Foo {
public synchronized void a() { //Do something }
public void b() {
synchronized(this) { // Do something }
}
public void c() { // Do something }
}
然后:
Foo foo = new Foo();
foo.a();
foo.b();
synchronized(foo) { foo.c(); }
这三种方法在同步方面都差不多。
没有“锁定”方法之类的东西。锁定仅在对象上完成。标记方法synchronized
只会使其锁定实例(或其静态方法的类对象)。
当您访问锁定对象上的方法时,该执行将被阻止,因为线程无法检索指定对象的 monitor -甚至在调用该方法之前。因此,foo.a()
在获得foo
时将被阻止。
我突然想起了什么。如果您的线程A调用了foo.a()
,并且要花很长时间才能完成,而此时另一个线程调用了foo.c()
,那么foo.c()
仍将被阻塞,直到{{1} }完成。