3個執行緒順序列印數字
阿新 • • 發佈:2018-12-31
問題:啟動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