2 回答

TA貢獻1725條經驗 獲得超8個贊
如果我鎖定了 foo,另一個線程可以調用 foo.instanceMethod() 嗎?
他們可以調用它,但調用將等到執行將您的塊synchronized打開foo,因為instanceMethodis synchronized。聲明一個實例方法與將其整個主體放在一個塊中synchronized大致相同。synchronizedthis
如果instanceMethod 沒有同步,那么呼叫當然不會等待。
但是請注意,synchronized您顯示的塊是不必要的:
synchronized(foo){ // <==== Unnecessary
foo.instanceMethod();
}
因為instanceMethodis synchronized,那只能是:
foo.instanceMethod();
...除非塊中還有其他東西。

TA貢獻1785條經驗 獲得超4個贊
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(); }
就同步而言,所有 3 種方法都非常等效。
沒有所謂的“鎖定”方法。鎖定僅對對象進行。標記方法synchronized只是使其鎖定實例(或其靜態方法的類對象)。
當您訪問鎖定對象上的方法時,執行將被阻止,因為線程無法檢索指定對象的監視器- 甚至在調用該方法之前。所以foo.a()在獲取foo.
加上...
我突然想起一件事。如果您有線程 A 調用foo.a()并且它需要很長時間才能完成,并且當時另一個線程調用foo.c(),那么foo.c()仍然會被阻塞直到foo.a()完成。
添加回答
舉報