java多執行緒程式設計之連續列印abc的幾種解法
阿新 • • 發佈:2019-01-07
java多執行緒程式設計之連續列印abc的解法
一道程式設計題如下:
例項化三個執行緒,一個執行緒列印a,一個執行緒列印b,一個執行緒列印c,三個執行緒同時執行,要求打印出10個連著的abc。
題目分析:
通過題意我們可以得出,本題需要我們使用三個執行緒,三個執行緒分別會列印6次字元,關鍵是如何保證順序一定是abc…呢。所以此題需要同步機制來解決問題!
令列印字元A的執行緒為ThreadA,列印B的ThreadB,列印C的為ThreadC。問題為三執行緒間的同步喚醒操作,主要的目的就是使程式按ThreadA->ThreadB->ThreadC->ThreadA迴圈執行三個執行緒,因此本人整理出了三種方式來解決此問題。
package com.demo.test;
通過兩個鎖(不推薦,可讀性和安全性比較差)
/**
* 基於兩個lock實現連續列印abcabc….
* @author GiggleXiang
*
*/
public class TwoLockPrinter implements Runnable {
// 列印次數 private static final int PRINT_COUNT = 10; // 前一個執行緒的列印鎖 private final Object fontLock; // 本執行緒的列印鎖 private final Object thisLock; // 列印字元 private final char printChar; public TwoLockPrinter(Object fontLock, Object thisLock, char printChar) { this.fontLock = fontLock; this.thisLock = thisLock; this.printChar = printChar; } @Override public void run() { // 連續列印PRINT_COUNT次 for (int i = 0; i < PRINT_COUNT; i++) { // 獲取前一個執行緒的列印鎖 synchronized (fontLock) { // 獲取本執行緒的列印鎖 synchronized (thisLock) { //列印字元 System.out.print(printChar); // 通過本執行緒的列印鎖喚醒後面的執行緒 // notify和notifyall均可,因為同一時刻只有一個執行緒在等待 thisLock.notify(); } // 不是最後一次則通過fontLock等待被喚醒 // 必須要加判斷,不然雖然能夠列印10次,但10次後就會直接死鎖 if(i < PRINT_COUNT - 1){ try { // 通過fontLock等待被喚醒 fontLock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public static void main(String[] args) throws InterruptedException { // 列印A執行緒的鎖 Object lockA = new Object(); // 列印B執行緒的鎖 Object lockB = new Object(); // 列印C執行緒的鎖 Object lockC = new Object(); // 列印a的執行緒 Thread threadA = new Thread(new TwoLockPrinter(lockC, lockA, 'A')); // 列印b的執行緒 Thread threadB = new Thread(new TwoLockPrinter(lockA, lockB, 'B')); // 列印c的執行緒 Thread threadC = new Thread(new TwoLockPrinter(lockB, lockC, 'C')); // 依次開啟a b c執行緒 threadA.start(); Thread.sleep(100); // 確保按順序A、B、C執行 threadB.start(); Thread.sleep(100); threadC.start(); Thread.sleep(100); }
}