2010-09-14 161 views
4

我有一個不尋常的問題。 我有一個函數,在這個函數中的操作可以一次由兩個線程完成。只允許兩個線程在一個函數上運行

static int iCount = 1; 
public synchronized void myFunct(){ 
while(iCount >= 3) 
{ 
    try { 
     wait(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
} 

iCount++; 

//Do Stuffs 
//After operation decrement count 

iCount --; 
notifyAll(); 
} 

我想要做的是,我想只允許兩個線程做一些操作,其他線程必須等待。

但是在這裏,前兩個線程遞增計數,並且操作和其他線程進入等待狀態,但沒有得到通知。

我想我是俯視的東西。

回答

11

聽起來像你想要使用Semaphore,你總是打電話acquire()在你做手術前,然後release()在finally塊。

private static final Semphore semaphore = new Semaphore(2); 

public static void myFunct() throws InterruptedException { 
    semaphore.aquire(); 
    try { 
     // do stuff 
    } finally { 
     semaphore.release(); 
    } 
} 
+0

是的。我可以使用信號量。但是我更關心上面這段代碼中的錯誤。 – 2010-09-14 13:22:24

+2

信號量已經存在了很長時間,您可以在這裏閱讀Dijkstra的原始文件 - http://userweb.cs.utexas.edu/users/EWD/transcriptions/EWD01xx/EWD123.html - 沒有重新發明輪子的意思除非它的某些操作系統課程或類似的部分,在這種情況下,你應該標記爲「家庭作業」 – 2010-09-14 13:35:59

1

您需要java.util.concurrent.Semaphore,用2個許可證進行初始化。

至於你當前的代碼 - 線程可能會緩存變量的值。嘗試添加volatile關鍵字。

2

您的功能是​​,因此一次只能有一個線程在其中。

我不確定我是否理解你的問題......但如果你想允許兩個線程一次去某個地方,看看Semaphore

1

這段代碼有很多問題。其中:

  1. 你必須上運行myFunct線程的數量沒有真正的控制權,因爲該方法在實例級上同步,而計數器是靜態的。因此,在N個不同實例上運行的N個不同線程可以同時運行相同的方法。

  2. 通過多個線程操作計數器不是線程安全的。考慮同步它或使用AtomicInteger。

關於線程數的限制,請考慮使用Semaphore類。

2

這是單身人士嗎? 如果不是那麼這是一個問題,因爲許多併發實例可能會更改icounter的值,並且它們會永遠阻塞它,因爲沒有線程將能夠調用通知他們的實例對象。

無論如何,你應該在函數內部移動同步並鎖定iCount,而不是實例,也使其變得易變。

public void myFunct(){ 
synchronized(iCount) { 
while(iCount >= 3) 
{ 
    try { 
     wait(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
} 
} 
iCount++; 
} 
//Do Stuffs 
//After operation decrement count 
synchronized(iCount) { 
iCount--; 
} 
notifyAll(); 
相關問題