2017-01-20 41 views
0

我有一個類的對象有一些狀態。 該對象有兩種方法(method1()method2()),都改變了obj的狀態。 method1()已同步但method2()未同步。如何在Java中實現類級同步?

現在兩個線程,線程1和threads2方法對象 - > threads1調用method1()其同步 - >線程2調用method2()這是不同步的。

我發現我的測試結果是method2()正在執行,即使method1()持有一個鎖。但我認爲,如果通過在方法上放置synchronized關鍵字來獲取整個對象的鎖定,則可以執行多少個其他方法。它應該等待。

您的意見非常感謝。

+2

你以爲是錯的。由於'method2'不同步,它不會嘗試獲取鎖,如果該鎖已被'method1'獲取,將會阻止該鎖。 – Kayaman

+0

有些代碼會很好。 –

+0

@Kayman我剛剛發現現在爲我工作。謝謝 –

回答

2

當我們說調用同步方法或塊導致鎖定時,所有這一切意味着線程獨佔獲取鎖。這並不意味着線程獲得鎖的對象的狀態會得到任何其他保護。

(爲了方便語言設計人員,將固有鎖連接到對象,包括類對象,該決定可能並不是最好的,使用專用對象鎖定通常是一個更好的主意。)

您的不同步呼叫可能會破壞共享狀態。除此之外,不存在內存屏障,並且調用非同步方法的線程所做的更改可能不會被其他線程看到。在進行優化如重新排序代碼時,JIT不會考慮跨線程可視性問題。

可能很難預測未充分同步的代碼中會發生什麼。

1

但我認爲,如果通過將同步方法放在整個對象上而不是如何執行任何其他方法來獲取鎖定。它應該等待。

鎖不知道它鎖定了什麼。它只是防止其他線程獲取相同的鎖。

1

這裏有一些很好的答案,但我認爲更多的細節是爲了。

我的測試結果發現,即使method1()有一個鎖,method2()仍然愉快地執行。

當線程輸入​​方法時,它鎖定與對象實例關聯的監視器。其他線程可以儘可能多地調用同一對象實例上的其他非同步方法。由thread1持有的鎖不以任何方式更改obj。只有當thread2去鎖相同對象實例將被阻止。

但我認爲,如果通過將同步方法放在整個對象上而不是如何執行任何其他方法來獲取鎖定。它應該等待。

不,事實並非如此。如果每個方法調用都必須查看是否在調用其方法的對象上存在鎖定,那麼會有很大的性能下降。