2014-11-03 67 views
0

考慮下面的代碼:如何實現自旋鎖,以避免阻塞

// Below block executed by thread t1 
synchronized(obj) { 
    obj.wait(0); 
} 

// This block executed by thread t2 
synchronized(obj) { 
    obj.notify(); 
} 

據我所知,在上面的代碼中,如果t1採取同步塊的所有權,並在同一時間,如果線程t2嘗試採取同步塊,然後t2進入內核等待。 我想避免這種情況,並在塊之前旋轉t2,直到t1調用等待並且保留塊的所有權。那可能嗎?

+0

請在提交之前花更多精力來設置您的帖子格式 - 使用預覽功能查看帖子的外觀,並且只有當它看起來您希望它看起來如果*您*正在回答問題時才提交。 – 2014-11-03 07:17:49

+6

另外,你有證據證明這實際上是在你的代碼中造成問題嗎?自旋鎖很少是正確的解決方案 - 並且牢記,只要調用wait(),t1將立即放棄鎖,因此t2阻塞的機會窗口非常小。 – 2014-11-03 07:20:22

+0

你爲什麼想這樣做?相反,在等待鎖的一個線程上,您將有一個線程等待鎖,同時浪費CPU週期。 – 2014-11-03 08:07:36

回答

1

JVM不需要實現作爲硬塊和上下文切換的鎖定同步塊的條目。它可以選擇使用較輕重量的方法,如自旋鎖。實際上,Oracle JVM需要一些時間來避免阻塞。所以你可能會發現JVM已經爲你做了這個優化。如果沒有,那可能是因爲JVM有證據表明自旋鎖將是一個壞主意。

+0

謝謝Raedwald,你能分享任何暗示這一點的鏈接。 – 2014-11-04 05:59:26

0

是的,可以做你想做的事。

接口java.util.concurrent.locks.Lock(如ReentrantLock)的實現允許您使用tryLock方法(從循環調用)忙等待鎖定。

爲了實現waitnotify功能,調用方法上LocknewCondition獲得Condition對象。 Condition接口具有類似於waitnotify/notifyAll的方法awaitsignal/signalAll