写点什么

蔚来手撕代码题:三个线程循环打印 ABC

作者:王磊
  • 2023-06-25
    陕西
  • 本文字数:1269 字

    阅读完需:约 4 分钟

蔚来手撕代码题:三个线程循环打印ABC

问题如下:



https://www.nowcoder.com/discuss/493178141461041152

思路分析

三个线程交替打印 ABC 的实现方法有很多,我个人比较倾向于使用 JUC 下的 CyclicBarrier(循环栅栏,也叫循环屏障)来实现,因为循环栅栏天生就是用来实现一轮一轮多线程任务的,它的核心实现思路如下图所示:



CyclicBarrier 作用是让一组线程相互等待,当达到一个共同点时,所有之前等待的线程再继续执行,且 CyclicBarrier 功能可重复使用。



上图描述的就是 CyclicBarrier 每轮等待 5 个线程全部达到一个共同点时,再执行下一阶段的任务。

举个例子

比如磊哥要坐班车回老家,因为中途不允许上、下乘客,那么营运的公司为了收益最大化,就会等人满之后再发车,这个发车的触发条件就是 CyclicBarrier 中多个线程执行的共同点。等汽车达到另一个站点之后也是同样的操作,等待乘客再次坐满之后,再继续发车,CyclicBarrier 就是这样执行的,它也是可以循环使用的。

实现代码

import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;
/** * 3 个线程交替打印 ABC */public class ThreadLoopPrint { // 共享计数器 private static int sharedCounter = 0; public static void main(String[] args) { // 打印的内容 String printString = "ABC"; // 定义循环栅栏 CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> { }); // 执行任务 Runnable runnable = new Runnable() { @Override public void run() { for (int i = 0; i < printString.length(); i++) { synchronized (this) { sharedCounter = sharedCounter > 2 ? 0 : sharedCounter; // 循环打印 System.out.println(printString.toCharArray()[sharedCounter++]); } try { // 等待 3 个线程都打印一遍之后,继续走下一轮的打印 cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } }; // 开启多个线程 new Thread(runnable).start(); new Thread(runnable).start(); new Thread(runnable).start(); }}
复制代码


以上程序执行的结果如下图所示:


小结

多线程循环打印主要是考察应聘者对于多线程模块掌握的情况,通过应聘者编写的代码和编写代码所用的时间,可以非常直观的了解应聘者的代码基本功。


本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

用户头像

王磊

关注

公众号:Java中文社群 2018-08-25 加入

公众号:Java中文社群

评论

发布
暂无评论
蔚来手撕代码题:三个线程循环打印ABC_java面试_王磊_InfoQ写作社区