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

45次阅读

共计 1446 个字符,预计需要花费 4 分钟才能阅读完成。

问题如下:

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、设计模式、音讯队列等模块。

正文完
 0