java 多线程输出_[Java多线程]ABC三个线程顺序输出的问题
大概的問題是這樣的:
有A,B,C三個線程, A線程輸出A, B線程輸出B, C線程輸出C
要求, 同時啟動三個線程, 按順序輸出ABC, 循環10次
這是一個多線程協同的問題, 本身多線程是沒有執行順序的, 順序不一定, Java在concurrent里面提供了多線程同步的支持
使用ReentrantLock來解決, 還有個state整數用來判斷輪到誰執行了
1 importjava.util.concurrent.locks.Lock;2 importjava.util.concurrent.locks.ReentrantLock;3
4 public classABC {5 private static Lock lock = new ReentrantLock();//通過JDK5中的鎖來保證線程的訪問的互斥
6 private static int state = 0;7
8 static class ThreadA extendsThread {9 @Override10 public voidrun() {11 for (int i = 0; i < 10;) {12 lock.lock();13 if (state % 3 == 0) {14 System.out.print("A");15 state++;16 i++;17 }18 lock.unlock();19 }20 }21 }22
23 static class ThreadB extendsThread {24 @Override25 public voidrun() {26 for (int i = 0; i < 10;) {27 lock.lock();28 if (state % 3 == 1) {29 System.out.print("B");30 state++;31 i++;32 }33 lock.unlock();34 }35 }36 }37
38 static class ThreadC extendsThread {39 @Override40 public voidrun() {41 for (int i = 0; i < 10;) {42 lock.lock();43 if (state % 3 == 2) {44 System.out.print("C");45 state++;46 i++;47 }48 lock.unlock();49 }50 }51 }52
53 public static voidmain(String[] args) {54 newThreadA().start();55 newThreadB().start();56 newThreadC().start();57 }58
59 }
使用lock來保證只有一個線程在輸出操作, 要保證了state不會被兩個線程同時修改, 思路簡單
還可以使用condition, condition的效率可能會更高一些, await會釋放lock鎖, condition的await和signal與object的wait和notify方法作用類似
1 importjava.util.concurrent.locks.Condition;2 importjava.util.concurrent.locks.Lock;3 importjava.util.concurrent.locks.ReentrantLock;4
5 public classABC2 {6 private static Lock lock = newReentrantLock();7 private static int count = 0;8 private static Condition A =lock.newCondition();9 private static Condition B =lock.newCondition();10 private static Condition C =lock.newCondition();11
12 static class ThreadA extendsThread {13
14 @Override15 public voidrun() {16 lock.lock();17 try{18 for (int i = 0; i < 10; i++) {19 while (count % 3 != 0)20 A.await(); //會釋放lock鎖
21 System.out.print("A");22 count++;23 B.signal(); //喚醒相應線程
24 }25 } catch(InterruptedException e) {26 e.printStackTrace();27 } finally{28 lock.unlock();29 }30 }31
32 }33
34 static class ThreadB extendsThread {35
36 @Override37 public voidrun() {38 lock.lock();39 try{40 for (int i = 0; i < 10; i++) {41 while (count % 3 != 1)42 B.await();43 System.out.print("B");44 count++;45 C.signal();46 }47 } catch(InterruptedException e) {48 e.printStackTrace();49 } finally{50 lock.unlock();51 }52 }53
54 }55
56 static class ThreadC extendsThread {57
58 @Override59 public voidrun() {60 lock.lock();61 try{62 for (int i = 0; i < 10; i++) {63 while (count % 3 != 2)64 C.await();65 System.out.println("C");66 count++;67 A.signal();68 }69 } catch(InterruptedException e) {70 e.printStackTrace();71 } finally{72 lock.unlock();73 }74 }75
76 }77
78 public static void main(String[] args) throwsInterruptedException {79 newThreadA().start();80 newThreadB().start();81 ThreadC threadC = newThreadC();82 threadC.start();83 threadC.join();84 System.out.println(count);85 }86 }
使用信號量也可以, 這個思路最簡單, 整個代碼也比較簡潔
1 importjava.util.concurrent.Semaphore;2
3 public classABC3 {4 private static Semaphore A = new Semaphore(1);5 private static Semaphore B = new Semaphore(1);6 private static Semaphore C = new Semaphore(1);7
8 static class ThreadA extendsThread {9
10 @Override11 public voidrun() {12 try{13 for (int i = 0; i < 10; i++) {14 A.acquire();15 System.out.print("A");16 B.release();17 }18 } catch(InterruptedException e) {19 e.printStackTrace();20 }21 }22
23 }24
25 static class ThreadB extendsThread {26
27 @Override28 public voidrun() {29 try{30 for (int i = 0; i < 10; i++) {31 B.acquire();32 System.out.print("B");33 C.release();34 }35 } catch(InterruptedException e) {36 e.printStackTrace();37 }38 }39
40 }41
42 static class ThreadC extendsThread {43
44 @Override45 public voidrun() {46 try{47 for (int i = 0; i < 10; i++) {48 C.acquire();49 System.out.println("C");50 A.release();51 }52 } catch(InterruptedException e) {53 e.printStackTrace();54 }55 }56
57 }58
59 public static void main(String[] args) throwsInterruptedException {60 B.acquire(); C.acquire(); //開始只有A可以獲取, BC都不可以獲取, 保證了A最先執行
61 newThreadA().start();62 newThreadB().start();63 newThreadC().start();64 }65 }
注意:
lock是需要lock所有者去釋放的, 即誰lock, 誰釋放, 不可以跨線程, 會報java.lang.IllegalMonitorStateException;
semaphore是沒有所有者的說法, 可以跨線程釋放和獲取.
這是一道java筆試題, 多線程的問題現在越來越多的出現在筆試中, 要好好學習.
水平有限, 如有錯漏, 請指針, 歡迎拍磚, 共同探討!
參考文獻:
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的java 多线程输出_[Java多线程]ABC三个线程顺序输出的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 曲线运动与万有引力公式_高考物理曲线运动
- 下一篇: future java 原理_Java线