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笔试题, 多线程的问题现在越来越多的出现在笔试中, 要好好学习.

水平有限, 如有错漏, 请指针, 欢迎拍砖, 共同探讨!

参考文献:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值