2013-06-25 52 views
0

我有以下情形: 多個事件來自源,每個都有不同的類型。我需要按順序對同一類型的每個事件進行一些操作,如果是其他類型,則需要並行操作。含義:線程沒有通知通知

從源活動: A1,A2,B1,A3,B2,C1

  • 監聽器A,必須排隊A1,A2和A3,並且在 順序與他們的工作,以單個線程
  • 監聽乙A相同,並行地,在不同的線程
  • 監聽器C與B相同,並行地,在不同的線程

我在做什麼來實現噸他?一般來說,我有一個監視器,每種類型的事件,我用一個新的線程初始化,然後調用wait()。每個監視器都有一個隊列。

Monitor.java(實現可運行)

public void run(){ 
    while(!killed){ 
    synchronize(this){  
     while(this.stopped){ 
     wait(); //it waits here when initialized, waiting for the first event 
     } 

     while(eventQueue.size() > 0){ 
     //do something with the event 
     } 

     //i set the flag stopped = true again to wait for the next event 
     this.stopped = true; 
    } 
    } 
} 

當一個事件到達時,我將其添加到隊列中,然後通知()顯示器以它打破了,同時

public void awake(Event event){ 
    synchronize(this){ 
    eventQueue.add(event); 
    this.stopped = false; 
    notify(); 
    } 
} 

的「殺死」標誌用於維持線程活着直到滿足某些標準。然後,我將死亡標誌設置爲true,並通知監視器結束線程。

我的問題是當我運行一組事件,有時線程不會喚醒notify()。有時10個事件中有10個會被處理,有時候會是10個事件中的8個,依此類推。

我一直在尋找通過並行api尋找一些替代我的問題,但我找不到任何好的。你們能否就我如何應對這個問題給我任何建議?

我希望我能很好地解釋我的問題。如果沒有,請詢​​問。

在此先感謝。

+0

供參考:this.stopped需要是volatile,因爲它被多個線程使用。 – Gray

+0

'notify()'或'notifyAll()'? – Raedwald

回答

5

「殺死」標誌用於維持線程處於活動狀態,直到滿足某些條件。然後,我將死亡標誌設置爲true,並通知監視器結束線程。

首先,我會認真考慮切換您的代碼使用BlockingQueue,如LinkedBlockingQueue。你仍然可以使用killed標誌(它必須是voltile btw),但是通過使用BlockingQueue所有的信號都是爲你處理的。你所要做的就是致電put()將事情添加到隊列中,並從take()中讀取。然後您不需要使用​​,waitnotify。您根本不需要stopped標誌。見下文。

while (!killed) { 
    Event event = eventQueue.take(); 
    ... 

我的問題是,當我運行一組事件,有時線程不清醒與通知()。有時10個事件中有10個會被處理,有時候會是10個事件中的8個,依此類推。

從目前的代碼錯誤的角度來看,我沒有看到任何問題,但魔鬼是在細節。有一點要記住的是,如果線程A調用notify(),則線程B調用wait()通知已經丟失。我想你想要做的事,如下列:

while(!killed){ 
    Event event; 
    synchronized (this) { 
     // wait until where is something in the queue 
     while(eventQueue.isEmpty()){ 
      this.wait(); 
     } 
     event = eventQueue.get(); 
    } 
    // work with event 
    ... 

這隻會如果隊列爲空,方式,它不需要stopped布爾。

+0

當我將事件放在隊列中時,我是否必須做特別的事情? (調用notify?),或者僅僅通過告訴eventQueue.put(event)將假設喚醒線程? – GoVeM

+0

您需要放置(...)'然後調用'notify()'來喚醒正在等待@GoVeM的用戶_if。如果你正在使用'BlockingQueue',那麼你不需要執行'notify()'。 – Gray

+0

我實際上正在嘗試使用'BlockingQueue'的解決方案,但是當我放置事件時,線程仍處於等待狀態。 – GoVeM