我一直在嘗試解決涉及線程通信使用wait()和notify()的問題。基本上我有2個線程T1和T2,我希望它們按以下順序執行:線程同步 - 如何執行線程交替
T1,T2,T1,T2 .....我怎麼能實現這個目標?
實際問題:有2個線程T1 - 打印奇數(比如1 - 100)和T2 - 打印偶數(1 - 100)。現在,輸出應該是1,2,3,4,5,.... 100
我一直在嘗試解決涉及線程通信使用wait()和notify()的問題。基本上我有2個線程T1和T2,我希望它們按以下順序執行:線程同步 - 如何執行線程交替
T1,T2,T1,T2 .....我怎麼能實現這個目標?
實際問題:有2個線程T1 - 打印奇數(比如1 - 100)和T2 - 打印偶數(1 - 100)。現在,輸出應該是1,2,3,4,5,.... 100
您描述了一個生產者 - 消費者模式。
這是在許多java書籍中描述的Java實現,包括由M. Ngton和Schildt撰寫的M.Grand「Patterns in Java。Volume I」和「Java 2:The Complete Reference」。
基本思路:兩個線程都應該使用1個監視器(即他們的代碼應該在synchronized(monitor) {}
塊內)。你還需要一些標誌變量,它應該表明兩個線程當前應該工作。
當你的一個線程在同步塊內部時,它應該檢查標誌變量是否輪到他做這項工作。如果是,讓它工作,然後更改標誌值,然後通知所有等待的線程。如果不是,那麼它應該等待。
它不完全是。基本上我有2個線程,可以說一個打印出來,另一個打印出來b。現在我想打印一個序列ababab ..... –
@sai你可以使用生產者 - 消費者的解決方案作爲解決方案。 –
您試圖並行化多步驟過程嗎?如果是這樣,請參閱我的回答here瞭解方法和一些工作代碼。答案涉及ExecutorService
(或兩個)和一個或多個工作隊列。
對於這種方法,您的處理需要能夠適合Runnable以及處理的中間狀態信息。 您將每個步驟作爲Runnable
作爲ExecutorService
加載,這將添加第二個Runnable以執行下一步。這保持了執行的順序,但是可以讓你有效地並行運行多個線程。
:編輯:
別人已經提出的,Exchanger庫類可用於這個,如果你明確要限制處理2個線程。我更喜歡上述方法,因爲它保持了執行順序,並且允許您完全使用現代4核(和8核)系統。它也應該減少一點同步。
看java.util.concurrent包,特別是Exchanger
如果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();
}
}
}
}
在單個線程中運行任務? –
如果你想要一些同步的東西,你爲什麼要用線程運行? – Guy
我產生了兩個線程。我希望它們交替執行,首先執行第一個線程 –