1. 程式人生 > >3個執行緒順序列印數字

3個執行緒順序列印數字

問題:啟動3個執行緒A、B、C,使A列印0,然後B列印1,然後C列印2,A列印3,B列印4,C列印5,依次類推。

思路:每個執行緒給定一個編號,每個執行緒判斷當前是否已經輪到自己列印:如果沒輪到,就wait等待;如果輪到,則列印當前數字,並喚醒其他執行緒。

判斷是否已經輪到自己列印:

每個執行緒給定一個編號N,N從0開始;

使用一個全域性變數記錄當前需要列印的數字C,C從0開始,每次列印之後加1;

執行緒數量M;

判斷邏輯:C%M ==N

舉例說明:3個執行緒M=3,執行緒編號N為0、1、2,

第一次執行,執行緒0判斷為true,執行緒1、執行緒2判斷為false,進入wait,則由執行緒0列印C=0,然後C++,然後喚醒其他執行緒;

執行緒0繼續迴圈發現判斷為false,進入wait;

執行緒1、執行緒2被喚醒,執行緒1判斷為true,執行緒2判斷為false,進入wait,則由執行緒1列印C=1,然後C++,然後喚醒其他執行緒;

執行緒1繼續迴圈發現判斷為false,進入wait;

執行緒0、執行緒2被喚醒,執行緒2判斷為true,執行緒0判斷為false,進入wait,則由執行緒2列印C=2,然後C++,然後喚醒其他執行緒;

依次迴圈,直到C超過給定的最大值,跳出迴圈。

public class PrintSequenceThread implements Runnable {

    private static final Object LOCK = new Object();

    /**
     * 當前即將列印的數字
     */
    private static int current = 0;

    /**
     * 當前執行緒編號,從0開始
     */
    private int threadNo;

    /**
     * 執行緒數量
     */
    private int threadCount;

    /**
     * 列印的最大數值
     */
    private int max;

    public PrintSequenceThread(int threadNo, int threadCount, int max) {
        this.threadNo = threadNo;
        this.threadCount = threadCount;
        this.max = max;
    }

    @Override
    public void run() {
        while(true) {
            synchronized (LOCK) {
                // 判斷是否輪到當前執行緒執行
                while (current % threadCount != threadNo) {
                    if (current > max) {
                        break;
                    }
                    try {
                        // 如果不是,則當前執行緒進入wait
                        LOCK.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 最大值跳出迴圈
                if (current > max) {
                    break;
                }
                System.out.println("thread-" + threadNo + " : " + current);
                current++;
                // 喚醒其他wait執行緒
                LOCK.notifyAll();
            }
        }
    }

    public static void main(String[] args) {
        int threadCount = 3;
        int max = 10;
        for(int i=0;i<threadCount;i++) {
            new Thread(new PrintSequenceThread(i,threadCount, max)).start();
        }
    }
}

輸出:

thread-0 : 0
thread-1 : 1
thread-2 : 2
thread-0 : 3
thread-1 : 4
thread-2 : 5
thread-0 : 6
thread-1 : 7
thread-2 : 8
thread-0 : 9
thread-1 : 10