2011-06-22 44 views
-1

您可以檢查此代碼是否會線程安全/替換同步的功能嗎?像限制訪問多個線程?替代Java中的「同步」關鍵字進行多線程

class CheckSynch{ 

    public static booloean check=true; 

    public static void func() // I am trying to write alternative code for synchronized function 
    { 
    if(check) { 
     check=false; 
     //body of function 
     check=true; 
     notifyAll(); 
    } else { 
     wait(); 
    } 
    } 
} 
+4

你的代碼示例很亂! – Rihards

+4

相信我,您無需爲synchronized關鍵字編寫替代方案。有人比你更聰明,已經設計好了,沒有冒犯性。 –

+3

這段代碼甚至不會運行,更不用說線程安全了。 wait/notify必須位於同步塊內,否則您無需等待或通知。 – Robin

回答

7

任何不使用正確同步的東西必然會中斷。如果您有兩個硬件線程,它們將同時運行,因此在檢查和修改check之間的時間內,可能會出現不同的線程並對其進行更改。

我不知道你爲什麼試圖迴避​​,但無論你想用非同步函數做什麼,它都不會工作,並最終會破壞非常難以重現的錯誤。

2

不,wait()需要在同步塊中。

0

總是建議在靜態方法中避免​​塊。

我EboMike同意,但如果你正在尋找基於讀/寫標準..你可以隨時使用ReentrantReadWriteLock

+2

可能值得解釋爲什麼建議「避免靜態方法中的同步塊」。 –

5

編寫自己的鎖定來阻塞線程/ sychronizaton是非常高級的主題,編寫代碼編譯不是一個高級話題。你必須問自己這是否是一個好主意。

你可以寫類似

final Lock lock = new ReentrantLock(); 

public static void func() { 
    lock.lock(); 
    try { 
     //body of function 
    } finally { 
     lock.unlock(); 
    } 
} 

但是,你有沒有說爲什麼要編寫您自己的同步。我假設它是因爲你不想等待1-2微秒獲取一個鎖。

您可以改爲使用繁忙循環。

final AtomicBoolean lock = new AtomicBoolean(); 

public static void func() { 
    // wait for the lock to be false and set it to true. 
    while(lock.getAndSet(true)); 
    try { 
     // body of function 
    } finally { 
     lock.set(false); 
    } 
} 
+0

@Peter Lawrey,我相信你的意思是'compareAndSet(false,true)'不'getAndSet(true)'。 +1是一個很好的選擇。 –

+0

你也可以做一個'compareAndSet',但'boolean'只有兩個可能的值。我會用你覺得更清楚的。 –

+0

@Peter,我試圖說服自己如何getAndSet將工作原來張貼。如果該值爲「false」,表示鎖定空閒。所以'while(lock.getAndSet(true))'總會在第一次失敗。但是,這就像打開了一道防洪門。通過它的第二次工作,其他每個線程的其他嘗試都是有效的,直到有人退出。如果數值被倒轉,我想它會起作用... –