2013-05-12 139 views
0

我正在嘗試編寫一個使用線程的Java程序。我希望能夠在程序啓動時運行3個線程,並讓他們在「工單」的ArrayList上等待。 最初,這將是沒有工作訂單。所以線程應該等待。 在未來的某個時間點,工作訂單將被添加到ArrayList中,並且主線程必須通知線程有工作要做。Java線程概念/演示

我想通過擴展Thread(而不是實現Runnable)來做到這一點。

我認爲我遇到的主要問題是線程與工作訂單ArrayList沒有正確同步。

我的代碼如下所示:

public static void main(String[] args) { 

    AnotherRunnable anotherRunnable = new AnotherRunnable(); 
    ArrayList<ATMRunnable> workOrders = new ArrayList<ATMRunnable>(); 

    T1 t1 = new T1(anotherRunnable, workOrders); 
    T1 t2 = new T1(anotherRunnable, workOrders); 

    t1.start(); 
    t2.start(); 

    try{ 
     Thread.sleep(2000); 
    } 
    catch(InterruptedException e){} 

     synchronized (workOrders){ 

     System.out.println(t1.getState() + " - " + t1.getName()); 
     System.out.println(t2.getState() + " - " + t2.getName()); 

     System.out.println("notify"); 
     workOrders.notify(); 

     System.out.println(t1.getState() + " - " + t1.getName()); 
     System.out.println(t2.getState() + " - " + t2.getName()); 

    } 
    } 

的AnotherRunnable類:

public class AnotherRunnable implements Runnable { 

public void run() 
{ 
    System.out.println("AnotherRunnable"); 

} 
} 

和胎面類:

公共類T1繼承Thread {

AnotherRunnable anotherRunnable; 
ArrayList<ATMRunnable> workOrders; 

ATMThread(AnotherRunnable anotherRunnable, ArrayList<ATMRunnable> workOrders) 
{ 
    this.anotherRunnable = anotherRunnable; 
    this.workOrders = workOrders; 
} 

public void run() 
{ 
    System.out.println("Run Thread"); 

    synchronized (workOrders){ 
     try{ 
      System.out.println("wait Thread"); 
      workOrders.wait(); 
     } 
     catch (InterruptedException e){} 
    } 

} 

}

這是程序的輸出:

Run Thread 
wait Thread 
Run Thread 
wait Thread 
WAITING - Thread-1 
WAITING - Thread-2 
notify all 
BLOCKED - Thread-1 
WAITING - Thread-2 

正如你所看到的,第一個線程的狀態改變到阻止,後電話通知的工作訂單對象。但是線程和可運行對象都不會被執行。

任何幫助將不勝感激。

+2

有相當多的問題 - 其中之一是,你永遠不會調用'anotherRunnable.run()',所以也沒有辦法,你可以看到'AnotherRunnable'印刷......你也叫'notify',不' notifyAll',所以只有一個線程被喚醒。 – assylias 2013-05-12 18:47:12

+0

@assylias線程調用'開始()'方法開始。 'run()'不應該從程序員代碼中調用。 – SJuan76 2013-05-12 18:48:14

+0

@ SJuan76除了'線程#run'方法已被重寫,所以'Runnable'的'run'方法不會被調用。 – assylias 2013-05-12 18:48:54

回答

0

我發現我必須做的才能讓它工作。主要是,這是缺少的概念。我不得不循環線程的運行方法。我在想每次調用notifyall時都會調用這個方法,這是不正確的。當對同步對象調用wait()時,該線程將停止,並且如果該代碼不在循環中,則會繼續執行,但不會執行。

0

您應該在java中使用併發集合以儘可能避免手動同步。

我希望能夠在程序啓動時運行3個線程,並讓他們在「工作訂單」的ArrayList上等待。最初,這將是沒有工作單。所以線程應該等待。在將來的某個時間點,工作訂單將被添加到ArrayList中,並且主線程必須通知線程有工作要做。

對於這種同步的,Blocking queues是你的朋友喜歡LinkedBlockingQueue這使得線程等待時,有隊列,或者當隊列已滿沒有項目。你不需要任何同步/等待/通知。

您還可以檢查是否有幫助:synchronization is risky

如果只是用於學習目的,你必須讓你同步正確先從邏輯。它沒有使用任何條件來等待或通知哪些是有問題的。它會工作,如果它是適當的,但它不是一個首選的方式。

+0

謝謝。我希望能夠手動完成,而不需要LinkedBlockingQueue。這只是一個理論練習。我需要理解爲什麼,在線程上運行沒有被調用。那是因爲我在ArrayList上同步的方式嗎? – oscarm 2013-05-13 16:45:21