2011-10-03 115 views
0

等待事件/更新的最佳方式是什麼?例如,我正在等待這個數據結構在做某事之前被更新。實現這一個循環裏面是不是最好的方法,因爲它會消耗大量的CPU時間,如:等待更新

while (true) { 
    // keep checking the data structure 
    // if data structure is updated 
    // break; 
} 
// do something here 

什麼是Java實現這樣的一個簡單而有效的方法?

回答

1

wait-notifyAll比循環更有效。

爲等待標準成語():

synchronized (obj) { 
    while(condition not hold) 
     obj.wait(); 
} 

但它的控制線程原始的方式,你在java.util.concurrent包最好用類。而且,如果我遇到這樣的問題,我會選擇克里斯戴爾的答案。

1

它確實取決於程序其餘部分的結構。我可能會首先查看java.util.concurrent,看看裏面的東西是否適合你。你可以做到這一點的方式

例子:

  • 期貨 - 如果你有一些「工作」要做,你可以有一個線程池執行服務來執行這項工作。當你致電submit()做你的工作時,你會得到一個未來,你可以檢查或阻止工作完成。

  • 隊列 - 如果您有一個組件正在執行此工作,並且有一個組件正在等待,您可以通過隊列完成它們的通信。任何時候只要處理完數據,都可以添加到隊列中。您可以使用LinkedBlockingQueue和poll()完成工作。

  • 監聽器 - 如果沒有併發性,您可以使用監聽器/觀察者模式。

根據您的應用程序結構有很多不同的選項。

+0

感謝這個信息太。 – jasonline

0

這是我會做的代碼示例。

在這個邏輯中我使用線程中的join方法。這確保在主線程執行繼續之前所有線程都已連接。我已將TODO放在需要添加代碼的位置

import java.util.ArrayList; 
import java.util.List; 

public class MultiThread extends Thread{ 

    public void run() { 
     System.out.println("Starting Thread - " + this.getName()+this.getThreadGroup()); 
     //TODO data structure is updated here 
    } 

    public static void main(String[] args) { 
     List dataStructureList = new ArrayList() ;//TODO need to replace with list of data structure 
     //TODO dataStructureList contain list of items 
     Thread[] threadArr = new Thread[dataStructureList.size()]; 
     for (int j = 0; j < threadArr.length; j++) { 
      threadArr[j] = new MultiThread(); 
      threadArr[j].setName("Thread " + j); 
      threadArr[j].start(); 
     } 
     try { 
      for (int j = 0; j < threadArr.length; j++) { 
       threadArr[j].join(); 
      } 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out.println("All thread finished"); 
     //TODO do something here 

    } 
} 
0

假設您在應用程序中使用多線程。要在多個線程中使用一個對象,應該使用同步。當一個線程初始化數據結構時,其他等待初始化完成。這個邏輯通常使用可以在任何對象上調用的等待/通知方法來實現。

工作線程(S):

while (initialized) { 
    synchronized (object) { 
    object.wait(); 
    } 
} 

初始化線程:

synchronized (object) { 
    // initialization 
    initialized = true; 
    object.notifyAll(); 
} 

object是數據結構,其應該初始化。 initialized標誌用於指示初始化已完成。最好使用此標誌,因爲有時wait可以在沒有對應的情況下完成notify