簡體   English   中英

線程同步 - 如何交替執行線程

[英]Thread Synchronization - How to execute threads alternatively

我一直在嘗試使用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.Grand“Patterns in Java。Volume I”和Naughton and Schildt的“Java 2:The Complete Reference”。

基本思想:兩個線程都應該使用1個監視器(即它們的代碼應該在synchronized(monitor) {}塊內)。 您還需要一些標志變量,它應該指示當前兩個線程中的哪一個應該工作。

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

查看java.util.concurrent包,特別是Exchanger

您正在嘗試並行化多步流程嗎? 如果是這樣,請在此處查看我的答案,以獲取方法和一些工作代碼。 答案涉及ExecutorService (或兩個)和一個或多個工作隊列。

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

:編輯:

正如另一個人所建議的那樣,如果您明確希望將處理限制為2個線程,則可以使用Exchanger庫類。 我更喜歡上述方法,因為它維護了執行順序,並允許您完全使用現代的4核(和8核)系統。 它還應該減少同步。

如果T1和T2是Runnable接口的2個不同實現,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();
        }
    }

}

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM