大概的问题是这样的:

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

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

参考文献:

java 多线程输出_[Java多线程]ABC三个线程顺序输出的问题相关推荐

  1. 如何实现ABC三个线程按顺序执行十次

    题目要求:创建三个线程,每个线程分别打印ABC,并按照ABC的顺序执行十次 题目可以使用多种不同的方式解决,下面我们分别使用 Condition 等待唤醒机制.Semaphore 信号量.CountD ...

  2. Java 三个线程依次输出ABC

    源于:https://lax.v2ex.com/t/547045#reply43 编写一个程序,开启 3 个线程 A,B,C,这三个线程的输出分别为 A.B.C,每个线程将自己的 输出在屏幕上打印 1 ...

  3. java三个线程 顺序执行_如何确保三个线程顺序执行

    三个线程t1.t2.t3.确保三个线程,t1执行完后t2执行,t2执行完后t3执行. 一.使用join thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程. ...

  4. C语言学习之编写一个C程序,运行时输人abc三个值,输出其中值最大者。

    编写一个C程序,运行时输人abc三个值,输出其中值最大者. #include <stdio.h> void main(){int a,b,c,max;printf("请输入三个数 ...

  5. c语言求abc大小时要怎么输入,C语言 有3个数a,b,c,要求按大小顺序把它们输出。,急!!!!!有三个数abc,要求按大小顺序输出. 请问用C语...

    导航:网站首页 > C语言 有3个数a,b,c,要求按大小顺序把它们输出.,急!!!!!有三个数abc,要求按大小顺序输出. 请问用C语 C语言 有3个数a,b,c,要求按大小顺序把它们输出., ...

  6. java三个整型变量_初值自定义.if按由小到大的顺序输出这三个数_C语言实现3个数从小到大排序/输出的方法示例...

    前言 本文主要给大家介绍了一个功能,任意输入 3 个整数,编程实现对这 3 个整数由小到大进行排序.下面话不多少了,来一起看看详细的介绍吧 实现过程: (1)定义数据类型,本实例中 a.b.c.t 均 ...

  7. java 鱼刺图_软件测试技术(三)——使用因果图法进行的UI测试

    目标程序 较上次增加两个相同的输入框 使用方法介绍 因果图法 在Introduction to Software Testing by Paul一书中,将软件测试的覆盖标准划分为四类,logical ...

  8. java tryparse用法_数据类型转换的三种方式 Convert,parse和TryParse的解析

    以Int类型为例,具体说明Convert.ToInt32(object value),int.Parse(object value)和int.TryParse(string s,out int res ...

  9. java取负数_[Java] 告别“CV 工程师”码出高效!(基础篇)

    作为一名资深的 CV 工程师,某天,当我再一次日常看见满屏的报错信息与键盘上已经磨的泛白的 Ctrl.C.V 这三个按键时,我顿悟了. 百度谷歌复制粘贴虽然很香,但是总是依靠前人种树,终会有一天失去乘 ...

最新文章

  1. 关于yum库的相关问题
  2. 新一届最强预训练模型上榜,出于BERT而胜于BERT
  3. 如何在github存储库中添加屏幕截图到README?
  4. Dialog的使用(二):AlertDialog.setItems
  5. SQL Server 2008 R2 安装时提示“Reporting Services目录数据库文件存在”
  6. 如何计算实际物理地址?
  7. qt动态添加窗口到垂直布局
  8. 【进阶3-5期】深度解析 new 原理及模拟实现
  9. 链路层到网络层的数据传递
  10. java设计模式之创建型设计模式
  11. vue引入iconfont阿里矢量图库
  12. 海风的Linux开发环境介绍
  13. Python os.popen() 方法
  14. 【Vegas原创】HP惠普笔记本重装系统无法引导无法进操作系统的终极解决方法
  15. 导出文件(图片、图片集)
  16. 【c#】MD5加密实现
  17. 淘宝足迹新玩法,如何通过足迹增加商品曝光量,打标后足迹不出解决方法,淘宝详情页的下拉出现足迹怎么实现的
  18. som神经网络聚类简单例子_深度聚类的可视化解释
  19. BI解析,告诉你企业为什么选择商业智能BI?
  20. 【java毕业设计】基于javaEE+原生Servlet+MySql的企业财务管理系统设计与实现(毕业论文+程序源码)——企业财务管理系统

热门文章

  1. extundelete安装_Linux数据安全工具:数据恢复软件extundelete概述
  2. 独立成分分析ICA系列4:ICA的最优估计方法综述
  3. 结合泛型与模板的STL.NET
  4. sqlserver 中的exec问题
  5. 如何用tadodataset.append
  6. Makefile中的patsubst函数
  7. ubuntu安装与配置nfs服务器
  8. STM32F103系列单片机学习笔记1方便以后查看
  9. 程序的加载和执行(四)——《x86汇编语言:从实模式到保护模式》读书笔记24
  10. UNIX再学习 -- 再识