2015-11-09
6:17 PM
在使用多執行緒我們常常需要使用到 synchronize 確保值的一致性
但是有一些情況很容易造成資料錯亂
這時我們就必須將某一些 Thread lock 住
直到確認其他 Thread 的前置工作完成了 才執行其他 Thread 的後續工作
以下就來介紹執行緒的 lock 該如何設計
本範例將以同一個 class 內的多個執行緒做個簡單示範
程式碼範例
// 宣告一個 final 的變數 將作為參數傳遞至各執行緒
private final Object locker = new Object();
// 宣告另一個變數 作為判斷是否需要 lock 執行緒
// 至於在各執行緒間的傳遞方式有很多種 在這裡就不多作介紹
private boolean commandLock = false;
// Thread 1
while(true){
if( !isConnected() ){
lostConnection = true;
break;
}
// 設定為 lock 狀態
commandLock = true;
// Do something
// 設定為 unlock 狀態 並喚醒上一個等待中的Thread
// 注意此處的 synchronized 是確保同時間只有一個執行緒操作 locker 物件
commandLock = false;
synchronized (locker) { locker.notify(); }
}
// Thread 2
public void reloadPage(){
commandLocker();
command( "Do reload" );
}
// Locker
private void commandLocker(){
// 檢查 lock 狀態 若為 lock 狀態則進行 wait 動作
// 直至 lock 狀態結束
synchronized (locker) {
while(commandLock){
try {
locker.wait();
} catch (InterruptedException e) {
logger.error("Thread sleep error in command locker section.");
}
}
}
}
可能有人會看過在 while loop 中不使用 obj.wait(); 的作法
而是使用 Thread.sleep(millis); 的方式
但此方式容易消耗過多的效能進行不必要的 loop 執行
而且若 millis 沒有設定好 若同時有其他 Thread.sleep(); 的動作
很有因為時間差而可能造成 locker 永遠不會被解除的問題
但若單純使用空的 while 那效能的浪費是非常可怕的
因此還是使用 synchronized 加上 locker 物件的方式會較適當
各項資料連結
Java - Synchronized
No comments:
Post a Comment