2016-11-06 41 views
1

我正在尋找關於如何使用Java中的鎖使此代碼線程安全的建議。我知道有很多關於鎖的問題。模糊的問題,競爭條件等可能會彈出。下面是我想要達到的基本理念,而天真的實現:使用Java排隊鎖

public class MultipleThreadWriter { 

boolean isUpgrading=false; 
boolean isWriting=false; 


public void writeData(String uniqueId) { 

    if (isUpgrading) 
     //block until isUpgrading is false 

    isWriting = true; 
    { 
     //do write stuff  
    } 
    isWriting = false; 

} 

public void upgradeSystem() { 

    if (isWriting) 
     //block until isWriting is false 

    isUpgrading = true; 
    { 
     //do updates 
    } 
    isUpgrading = false; 

} 

} 

的基本思路是,多線程允許同時寫入數據。沒關係,因爲沒有兩個線程會寫入與同一uniqueId有關的數據。但是,「系統升級」操縱所有uniqueIds的數據,所以它必須阻塞(等待)直到沒有數據寫入才能啓動,此時它會阻止所有寫入直到完成。 (絕對不是在這裏進行的消費者/生產者模式 - 升級發生任意,即與正在寫入的數據沒有關係。)

回答

0

根據@DaoWen的回答,這是我未經測試的解決方案。

public class MultipleThreadWriter { 

private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 
private final Lock r = rwl.readLock(); 
private final Lock w = rwl.writeLock(); 


public void writeData() { 

    r.lock(); 
    try { 
     //do write stuff  
    } finally { 
     r.unlock(); 
    } 

} 

public void upgradeSystem() { 

    w.lock(); 
    try { 
     //do updates 
    } finally { 
     w.unlock(); 
    } 

} 
} 
2

這聽起來像是一個很好的應用程序readers-writer lock

但是,在這種情況下,您的「讀者」是可以同時運行的小型更新任務,而您的「編寫者」是系統升級任務。

有這個在Java標準庫的實現:

java.util.concurrent.locks.ReentrantReadWriteLock

鎖已公平非公平模式。如果您希望系統升級在計劃完成後儘快運行,請使用鎖定模式公平。如果您希望在空閒時間內應用升級(即等到沒有小的更新進行),則可以使用不公平的模式。

由於這是讀者鎖定器(你的讀者實際上也在寫作!)的一個非正統的應用程序的一部分,請務必在您的代碼中評論這個。你甚至可以考慮寫一個ReentrantReadWriteLock類的包裝,它提供了localUpdateLockglobalUpdateLock方法,分別代表readLockwriteLock

+0

謝謝。根據你的想法,我創建了這個解決方案: 'public class MultipleThreadWriter { private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); private final Lock w = rwl.writeLock(); \t \t \t公共無效寫數據(){ \t \t \t r.lock(); \t \t嘗試{\t \t \t \t //做寫東西\t \t \t} {終於 \t \t \t河開鎖(); \t \t} \t \t \t \t } \t \t 公共無效upgradeSystem(){ \t \t \t \t w.lock(); \t \t嘗試{ \t \t \t //做更新 \t \t} {終於 \t \t \t w.unlock(); \t \t} \t} }' – bitsmcgee77

+0

對評論中難以辨認的代碼感到抱歉!無法弄清楚我的生活如何讓它正確格式化。 – bitsmcgee77