当前位置: 首页 > news >正文

面试题:ABCD四个线程,A线程最后执行

我觉得是一个很高频的面试题,ABCD四个线程,A线程要等到BCD线程执行完再执行,怎么做
因为我刚复习完AQS,所以立马想到了CountDownLatch,但是看面试官反应他最想听到的应该是join方法,所以面试后就总结了几种方法。
1、join
2、CountDownLatch
3、核心线程数为1的线程池

1、Join方法

Thread提供了让一个线程等待另一个线程完成的方法——join方法。当在某个程序执行流中调用其他线程的join方法时,调用线程将被阻塞,直到被调用join方法加入的join线程执行完毕

public class ThreadJoinDemo {public static void main(String[] args) throws InterruptedException {Thread B = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("B线程启动");}});Thread C = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("C线程启动");}});Thread D = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("D线程启动");}});Thread A = new Thread(new Runnable() {@Overridepublic void run() {try {B.join();C.join();D.join();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("A线程启动");}});A.start();D.start();C.start();B.start();}
}

结果:

D线程启动
C线程启动
B线程启动
A线程启动

2、CountDownLatch

CountDownLatch(闭锁)是一个同步协助类,允许一个或者多个线程等待,直到其他线程完成操作集。
CountDownLatch使用给定的数值(count)初始化,await方法会阻塞直到当前的计数值(count)由于countDown方法的调用达到0,count为0后所有等待的线程都会被释放,并且随后对await方法的调用都会立即返回,这个是个一次性的现象(相比CyclicBarrier会重置count)。

public class ThreadCountDownLatchDemo {public static void main(String[] args) {CountDownLatch countDownLatch = new CountDownLatch(3);new Thread(()->{countDownLatch.countDown();System.out.println("线程B启动");}).start();new Thread(()->{countDownLatch.countDown();System.out.println("线程C启动");}).start();new Thread(()->{countDownLatch.countDown();System.out.println("线程D启动");}).start();new Thread(()->{try {countDownLatch.await();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("线程A启动");}).start();}
}

结果:

线程B启动
线程C启动
线程D启动
线程A启动

CountDownLatch与Thread.join的区别

  • CountDownLatch的作用就是允许一个或多个线程等待其他线程完成操作,看起来有点类似join() 方法,但其提供了比 join() 更加灵活的API。
  • CountDownLatch可以手动控制在n个线程里调用n次countDown()方法使计数器进行减一操作,也可以在一个线程里调用n次执行减一操作。
  • 而 join() 的实现原理是不停检查join线程是否存活,如果 join 线程存活则让当前线程永远等待。所以两者之间相对来说还是 countDownLatch使用起来较为灵活。

3、线程池

JAVA通过Executors提供了四种线程池

单线程化线程池(newSingleThreadExecutor);
可控最大并发数线程池(newFixedThreadPool);
可回收缓存线程池(newCachedThreadPool);
支持定时与周期性任务的线程池(newScheduledThreadPool)。
单线程化线程池(newSingleThreadExecutor):优点,串行执行所有任务。

submit():提交任务。
shutdown():方法用来关闭线程池,拒绝新任务。
使用核心线程数为1的线程池,保证线程的执行顺序按照线程的提交顺序执行。
应用场景:串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

public class ThreadPoolDemo {public static void main(String[] args) {ExecutorService executorService = Executors.newSingleThreadExecutor();
//        ExecutorService executorService1 = Executors.newFixedThreadPool(1);Thread A = new Thread(() -> {System.out.println("启动线程A");});Thread B = new Thread(() -> {System.out.println("启动线程B");});Thread C = new Thread(() -> {System.out.println("启动线程C");});Thread D = new Thread(() -> {System.out.println("启动线程D");});executorService.submit(D);executorService.submit(C);executorService.submit(B);executorService.submit(A);executorService.shutdown();}
}

结果:

启动线程D
启动线程C
启动线程B
启动线程A
http://www.lryc.cn/news/470187.html

相关文章:

  • 代码随想录算法训练营第46期Day43
  • 前端处理API接口故障:多接口自动切换的实现方案
  • 多租户架构的全景分析(是什么?基本概念、实现策略、资源管理和隔离、数据安全与隔离、性能优化、扩展性与升级、案例研究)
  • Git使用问题汇总附带解决方法(持续更新)
  • Spring Boot驱动的植物健康监测革命
  • element 中 el-dialog 在不同的文件中使用
  • QT中采用QCustomPlot 实现将buffer中的数据绘制成折线图,并且图形随着数据更新而更新
  • 1688API商品详情接口如何获取
  • pytorch + d2l环境配置
  • Go使用exec.Command() 执行脚本时出现:file or directory not found
  • 细节性知识(宏定义解析与宏的外部引用)
  • 面试中的JVM:结合经典书籍的深度解读
  • 使用语音模块的开发智能家居产品(使用雷龙LSYT201B 语音模块)
  • 深入理解支持向量机:从基本原理到实际应用
  • 每天一题:洛谷P2041分裂游戏
  • 简单的 curl HTTP的POSTGET请求以及ip port连通性测试
  • ubuntu下快捷键启动程序
  • Yii2 init 初始化脚本分析
  • 深入理解gPTP时间同步过程
  • 基于阿里云服务的移动应用日志管理方案—日志的上传、下载、存档等
  • Python浪漫之画星星
  • Android使用协程实现自定义Toast弹框
  • git diff命令详解
  • Vue 插槽:组件通信的“隐形通道”
  • react1816中的setState同步还是异步的深层分析
  • 【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第七篇-体积纹理绘制】
  • Linux的环境搭建
  • WPF+Mvvm案例实战(五)- 自定义雷达图实现
  • 网络爬虫-Python网络爬虫和C#网络爬虫
  • 如何有效解除TikTok账号间的IP关联