控制三個線程按順序交替輸出數字123123…
synchronized(配合專用鎖對象)
通過共享鎖和 volatile 變量控制執行順序,每個線程按指定順序打印指定內容,確保輸出序列如 “123123…”。使用 synchronized
和 wait/notifyAll
實現線程間協作。
/*** AlternateOutput類用于實現三個線程交替輸出數字的功能* 通過使用synchronized關鍵字和wait/notify機制,確保三個線程按照1->2->3的順序循環輸出*/
public class AlternateOutput {/*** 用于線程同步的鎖對象*/private static final Object lock = new Object();/*** 當前應該執行的線程編號*/private static int currentThreadNum = 1;/*** 每個線程需要執行的循環次數*/private static final int MAX_LOOP = 10;/*** 線程執行的任務方法,負責按照指定順序輸出內容* @param curThreadNum 當前線程的編號,用于判斷是否輪到當前線程執行* @param nextThreadNum 下一個應該執行的線程編號,執行完當前任務后更新此值* @param output 當前線程需要輸出的內容*/private static void runTask(int curThreadNum, int nextThreadNum, String output) {// 循環執行指定次數的任務for (int i = 0; i < AlternateOutput.MAX_LOOP; i++) {// 使用synchronized塊確保線程安全synchronized (lock) {// 等待直到輪到當前線程執行while (AlternateOutput.currentThreadNum != curThreadNum) {try {lock.wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();return;}}// 輸出當前線程的內容System.out.print(output);// 更新下一個應該執行的線程編號currentThreadNum = nextThreadNum;// 喚醒所有等待的線程lock.notifyAll();}}}/*** 程序入口點,創建并啟動三個線程實現交替輸出* @param args 命令行參數*/public static void main(String[] args) {// 創建第一個線程,負責輸出"1"Thread t1 = new Thread(() -> {runTask(1, 2, "1");});t1.start();// 創建第二個線程,負責輸出"2"Thread t2 = new Thread(() -> {runTask(2, 3, "2");});t2.start();// 創建第三個線程,負責輸出"3"Thread t3 = new Thread(() -> {runTask(3, 1, "3");});t3.start();// 等待所有線程執行完成try {t1.join();t2.join();t3.join();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}
ReentrantLock和Condition
通過ReentrantLock
和Condition
控制執行順序,確保按1→2→3循環打印10次。每個線程等待其編號輪次,執行打印后喚醒下一個線程。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class PrintNumber {public static final int MAX_LOOP = 10;public static int currentNum = 1;public static final ReentrantLock lock = new ReentrantLock();public static final Condition c1 = lock.newCondition();public static final Condition c2 = lock.newCondition();public static final Condition c3 = lock.newCondition();public static void main(String[] args) {Thread t1 = new Thread(new PrintNumberTask(1));Thread t2 = new Thread(new PrintNumberTask(2));Thread t3 = new Thread(new PrintNumberTask(3));t1.start();t2.start();t3.start();}
}
import java.util.concurrent.locks.Condition;public class PrintNumberTask implements Runnable {private int number;public PrintNumberTask(int num) {this.number = num;}private void printAndSwith(String output, int nextNum, Condition awaitCondition, Condition signalCondition)throws InterruptedException {while (PrintNumber.currentNum != this.number) {awaitCondition.await();}System.out.print(output);PrintNumber.currentNum = nextNum;signalCondition.signal();}@Overridepublic void run() {for (int i = 0; i < PrintNumber.MAX_LOOP; i++) {PrintNumber.lock.lock();try {switch (number) {case 1:printAndSwith("1", 2, PrintNumber.c1, PrintNumber.c2);break;case 2:printAndSwith("2", 3, PrintNumber.c2, PrintNumber.c3);break;case 3:printAndSwith("3", 1, PrintNumber.c3, PrintNumber.c1);break;default:break;}} catch (Exception e) {e.printStackTrace();} finally {PrintNumber.lock.unlock();}}}
}