2010-02-14 103 views
3

我一直在嘗試解決涉及線程通信使用wait()和notify()的問題。基本上我有2個線程T1和T2,我希望它們按以下順序執行:線程同步 - 如何執行線程交替

T1,T2,T1,T2 .....我怎麼能實現這個目標?

實際問題:有2個線程T1 - 打印奇數(比如1 - 100)和T2 - 打印偶數(1 - 100)。現在,輸出應該是1,2,3,4,5,.... 100

+3

在單個線程中運行任務? –

+0

如果你想要一些同步的東西,你爲什麼要用線程運行? – Guy

+0

我產生了兩個線程。我希望它們交替執行,首先執行第一個線程 –

回答

2

您描述了一個生產者 - 消費者模式。

這是在許多java書籍中描述的Java實現,包括由M. Ngton和Schildt撰寫的M.Grand「Patterns in Java。Volume I」和「Java 2:The Complete Reference」。

基本思路:兩個線程都應該使用1個監視器(即他們的代碼應該在synchronized(monitor) {}塊內)。你還需要一些標誌變量,它應該表明兩個線程當前應該工作。

當你的一個線程在同步塊內部時,它應該檢查標誌變量是否輪到他做這項工作。如果是,讓它工作,然後更改標誌值,然後通知所有等待的線程。如果不是,那麼它應該等待。

+0

它不完全是。基本上我有2個線程,可以說一個打印出來,另一個打印出來b。現在我想打印一個序列ababab ..... –

+2

@sai你可以使用生產者 - 消費者的解決方案作爲解決方案。 –

1

您試圖並行化多步驟過程嗎?如果是這樣,請參閱我的回答here瞭解方法和一些工作代碼。答案涉及ExecutorService(或兩個)和一個或多個工作隊列。

對於這種方法,您的處理需要能夠適合Runnable以及處理的中間狀態信息。 您將每個步驟作爲Runnable作爲ExecutorService加載,這將添加第二個Runnable以執行下一步。這保持了執行的順序,但是可以讓你有效地並行運行多個線程。

:編輯:

別人已經提出的,Exchanger庫類可用於這個,如果你明確要限制處理2個線程。我更喜歡上述方法,因爲它保持了執行順序,並且允許您完全使用現代4核(和8核)系統。它也應該減少一點同步。

0

如果T1和T2是2種不同的Runnable接口的實現方式中,與T1是(一個線程,打印只是奇數1,3,。 ..)和T2是打印偶數(1,2 .....)的一種,這可以通過在共享監視器上使用wait()和notify()方法來完成。重要的是每個線程在打印其值之前檢查共享標誌。下面的代碼有效;

//The shared monitor 
public class Mutex { 
public static boolean oddFlag; 

} 

//The Thread that is supposed to print Odd numbers (assuming an upper limit of 99) 
public class OddPrinter implements Runnable { 
private Mutex mutex; 

public OddPrinter(Mutex mutex) { 
    this.mutex = mutex; 
} 

public synchronized void run() { 
    System.out.println("Started Thread: OddPrinter"); 
    int i; 
    for(i=1; i<100; i+=2) { 
     synchronized (mutex) { 
      while(!Mutex.oddFlag) { 
       try { 
        mutex.wait(); 
       } catch (InterruptedException ie) { 
        Thread.currentThread().interrupted(); 
       } 
      } 

      if(Mutex.oddFlag == true) { 
       System.out.println("Print from OddPrinter: "+i); 
       Mutex.oddFlag = false; 
       mutex.notify(); 
      } 


     } 
    } 
    System.out.println("Finished Thread: OddPrinter: "+i); 
} 

} 

//The Thread that is supposed to print Odd numbers (assuming an upper limit of 98) 
public class EvenPrinter implements Runnable { 
private Mutex mutex; 

public EvenPrinter(Mutex mutex) { 
    this.mutex = mutex; 
} 

public synchronized void run() { 
    System.out.println("Started Thread: EvenPrinter"); 
    int i; 
    for(i=2; i<100; i+=2) { 
     synchronized (mutex) { 
      while(Mutex.oddFlag) { 
       try { 
        mutex.wait(); 
       } catch (InterruptedException ie) { 
        Thread.currentThread().interrupted(); 
       } 
      } 

      if(!(Mutex.oddFlag == true)) { 
       System.out.println("Print from EvenPrinter: "+i); 
       Mutex.oddFlag = true; 
       mutex.notify(); 
      } 

     } 
    } 
    System.out.println("Finished Thread: EvenPrinter: "+i); 
} 

} 

//The test harness that executes the threads 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class NumberPrinterTest { 

public static void main(String[] args) throws Exception{ 
    ExecutorService es = Executors.newFixedThreadPool(2); 

    Mutex mutex = new Mutex(); 
    OddPrinter op = new OddPrinter(mutex); 
    EvenPrinter ep = new EvenPrinter(mutex); 
    Mutex.oddFlag = true; 
    es.execute(op); 
    es.execute(ep); 

    if(null != es){ 
     es.shutdown(); 
     try { 
      es.awaitTermination(1, TimeUnit.MINUTES); 
     } catch (InterruptedException e) { 
      Thread.currentThread().interrupted(); 
     } 
    } 

} 

}