三个线程按顺序打印ABC?十二种做法,深入多线程同步通信机制

本文介绍了如何使用synchronized、lock、volatile、AtomicInteger、Condition、Semaphore、CountDownLatch、CyclicBarrier、Exchanger、ThreadLocal、PipedStream和BlockingQueue等工具,实现三个线程按A-B-C的顺序打印。详细解析了每种方法的实现思路和代码,帮助理解Java线程同步和通信机制。
摘要由CSDN通过智能技术生成

大家好,我是老三,这篇文章分享一道非常不错的题目:三个线程按序打印ABC。

很多读者朋友应该都觉得这道题目不难,这次给大家带来十二种做法,一定有你没有见过的新姿势。

1. synchronized+wait+notify

说到同步,我们很容易就想到synchronized。

线程间通信呢?我们先回忆一下线程间的调度。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

多线程常见调度方法

可以看到,等待和运行之间的转换可以用wait和notify。

那么整体思路也就有了:

  • 打印的时候需要获取锁

  • 打印B的线程需要等待打印A线程执行完,打印C的线程需要等待打印B线程执行完

编辑切换为居中

添加图片注释,不超过 140 字(可选)

ABC-1

  • 代码

 
 

public class ABC1 { //锁住的对象 private final static Object lock = new Object(); //A是否已经执行 private static boolean aExecuted = false; //B是否已经执行过 private static boolean bExecuted = false; public static void printA() { synchronized (lock) { System.out.println("A"); aExecuted = true; //唤醒所有等待线程 lock.notifyAll(); } } public static void printB() throws InterruptedException { synchronized (lock) { //获取到锁,但是要等A执行 while (!aExecuted) { lock.wait(); } System.out.println("B"); bExecuted = true; lock.notifyAll(); } } public static void printC() throws InterruptedException { synchronized (lock) { //获取到锁,但是要等B执行 while (!bExecuted) { lock.wait(); } System.out.println("C"); } } }

  • 测试:后面几种方法的单测基本和这种方法一致,所以后面的单测就省略了。

 
 

@Test void abc1() { //线程A new Thread(() -> { ABC1.printA(); }, "A").start(); //线程B new Thread(() -> { try { ABC1.printB(); } catch (InterruptedException e) { e.printStackTrace(); } }, "B").start(); //线程C new Thread(() -> { try { ABC1.printC(); } catch (InterruptedException e) { e.printStackTrace(); } }, "C").start(); }

2. lock+全局变量state

还可以用lock+state来实现,大概思路:

  • 用lock来实现同步

  • 用全局变量state标识改哪个线程执行,不执行就释放锁

编辑切换为居中

添加图片注释,不超过 140 字(可选)

lock+state

  • 代码

 
 

public class ABC2 { //可重入锁 private final static Lock lock = new ReentrantLock(); //判断是否执行:1表示应该A执行,2表示应该B执行,3表示应该C执行 private static int state = 1; public static void printA() { //自旋 while (state < 4) { try { //获取锁 lock.lock(); //并发情况下,不能用if,要用循环判断等待条件,避免虚假唤醒 while (state == 1) { System.out.println("A"); state++; } } finally { //要保证不执行的时候,锁能释放掉 lock.unlock(); } } } public static void printB() throws InterruptedException { while (state < 4) { try { lock.lock(); //获取到锁,应该执行 while (state == 2) { System.out.println("B"); state++; } } finally { lock.unlock(); } } } public static void printC() throws InterruptedException { while (state < 4) { try { lock.lock(); while (state == 3) { //获取到锁

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值