当前位置: 首页 > 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

相关文章:

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

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

代码随想录算法训练营第46期Day43

leetcode.322零钱兑换 class Solution { public: //无限个硬币->完全背包int coinChange(vector<int>& coins, int amount) {vector<int> dp(10010,INT_MAX);//dp代表的在某个数值下最小的硬币数&#xff0c;要求是最小的硬币数&#xff0c;所以初始值要尽可…...

前端处理API接口故障:多接口自动切换的实现方案

因为在开发APP&#xff0c;一个接口如果不通&#xff08;被挂了&#xff09;又不能改了重新打包让用户再下载软件更新&#xff0c;所以避免这种情况&#xff0c;跟后端讨论多备用接口地址自动切换的方案&#xff0c;自动切换到备用的接口地址&#xff0c;并保证后续所有的请求都…...

多租户架构的全景分析(是什么?基本概念、实现策略、资源管理和隔离、数据安全与隔离、性能优化、扩展性与升级、案例研究)

文章目录 1. 多租户的基本概念2. 多租户的实现策略2.1 独立数据库模式2.2 共享数据库-独立Schema模式2.3 共享数据库-共享Schema模式 3. 资源管理和隔离4. 数据安全与隔离5. 性能优化6. 扩展性与升级7. 案例研究总结 多租户架构在云计算和SaaS应用中越来越流行&#xff0c;因为…...

Git使用问题汇总附带解决方法(持续更新)

Git使用问题汇总附带解决方法 一 git pull 代码时报错&#xff1a; Auto packing the repository in background for optimum performance. See “git help gc“ 一 git pull 代码时报错&#xff1a; Auto packing the repository in background for optimum performance. See …...

Spring Boot驱动的植物健康监测革命

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理植物健康系统的相关信息成为必然。开发合适…...

element 中 el-dialog 在不同的文件中使用

在实际中工作&#xff0c;我们经常需要使用 el-dialog 来做一个弹框的功能。最常见的就是在父组件中点击一个按纽&#xff0c;然后弹出一个框。而这个框就是子组件。同时&#xff0c;父子组件是分布在不同的文件中。 <!--父组件--> <template> <div> <…...

QT中采用QCustomPlot 实现将buffer中的数据绘制成折线图,并且图形随着数据更新而更新

QT中采用QCustomPlot 实现将buffer中的数据绘制成折线图,并且图形随着数据更新而更新 为了在 Qt 中将缓冲区的数据动态绘制成折线图,并随着数据的更新而实时更新,可以使用 QCustomPlot 或 Qt 自带的绘图功能,比如 QGraphicsView,或者在更简单的情况下使用 QPainter 在 QW…...

1688API商品详情接口如何获取

获取 1688API商品详情接口主要有以下步骤&#xff1a; 一、注册开发者账号&#xff1a; 访问 1688 开放平台&#xff0c;进行开发者账号注册。这是获取 API 接口使用权限的第一步&#xff0c;注册信息要确保真实准确。 二、了解接口规范和政策&#xff1a; 在 1688 开放平台…...

pytorch + d2l环境配置

文章目录 前言一、安装软件二、配置具体环境 前言 一直想写一篇 pytorch d2l的深度学习环境配置。但一直都不是很顺利&#xff0c;配置过很多次&#xff0c;都会遇到一些各种依赖项的兼容性问题。但这个是没有办法的&#xff0c;各种开源包都在不断维护过程中&#xff0c;版本…...

Go使用exec.Command() 执行脚本时出现:file or directory not found

使用 Go 提供的 exec.Command() 执行脚本时出现了未找到脚本的 bug&#xff0c;三个排查思路 &#xff1a; exec.Command(execName, args…) 脚本名字不允许相对路径 exec.Command(execName, args…) execName 只能有脚本名&#xff0c;不允许出现参数 如果你是使用 Windows …...

细节性知识(宏定义解析与宏的外部引用)

目录 一、问&#xff1a;#define N 50 中的N可以用来做运算比较吗&#xff1f; 二、宏定义怎么外部引用&#xff1f; 例子 总结 一、问&#xff1a;#define N 50 中的N可以用来做运算比较吗&#xff1f; 解析&#xff1a;在C语言中&#xff0c;#define N 50 是一个预处理指…...

面试中的JVM:结合经典书籍的深度解读

写在前面 &#x1f525;我把后端Java面试题做了一个汇总&#xff0c;有兴趣大家可以看看&#xff01;这里&#x1f449; ⭐️在无数次的复习巩固中&#xff0c;我逐渐意识到一个问题&#xff1a;面对同样的面试题目&#xff0c;不同的资料来源往往给出了五花八门的解释&#…...

使用语音模块的开发智能家居产品(使用雷龙LSYT201B 语音模块)

在这篇博客中&#xff0c;我们将探讨如何使用 LSYT201B 语音模块 进行智能设备的语音交互开发。通过这个模块&#xff0c;我们可以实现智能设备的语音识别和控制功能&#xff0c;为用户带来更为便捷和现代的交互体验。 1. 语音模块介绍 LSYT201B 是一个基于“芯片算法”的语音…...

深入理解支持向量机:从基本原理到实际应用

第6章 支持向量机 在本章中&#xff0c;我们将深入探讨支持向量机&#xff08;SVM&#xff09;这一强大的分类算法。SVM在模式识别和机器学习领域广泛应用&#xff0c;尤其在处理高维数据时表现出色。我们将依次讨论间隔与支持向量、对偶问题、核函数、间隔与正则化、支持向量…...

每天一题:洛谷P2041分裂游戏

题目描述 有一个无限大的棋盘&#xff0c;棋盘左下角有一个大小为 n 的阶梯形区域&#xff0c;其中最左下角的那个格子里有一枚棋子。你每次可以把一枚棋子“分裂”成两枚棋子&#xff0c;分别放在原位置的上边一格和右边一格。&#xff08;但如果目标位置已有棋子&#xff0c…...

简单的 curl HTTP的POSTGET请求以及ip port连通性测试

简单的 curl HTTP的POST&GET请求以及ip port连通性测试 1. 需求 我们公司有一个演示项目&#xff0c;需要到客户那边进行项目部署&#xff0c;项目部署完成后我们需要进行项目后端接口的测试功能&#xff0c;但是由于客户那边么有条件安装类似于postman这种的测试工具&am…...

ubuntu下快捷键启动程序

背景&#xff1a;公司自开发的软件&#xff0c;经常需要启动&#xff0c;每次去找目录启动很麻烦&#xff0c;所以想快捷启动 方法1&#xff1a; 通过编辑.baserc启动 例如启动程序是toolA, 放在/home/user/software/目录下&#xff0c;那么在~/.baserc里面加入一行代码 al…...

Yii2 init 初始化脚本分析

脚本目的&#xff1a; init 脚本主要的作用是&#xff1a;从 environments 目录中复制配置文件&#xff0c;确保应用适配不同环境&#xff08;例如开发、生产环境等&#xff09;。 工作流程&#xff1a; 获取 $_SERVER 的 argv 参数 加载 environments/index.php 文件&#…...

深入理解gPTP时间同步过程

泛化精确时间协议(gPTP)是一个用于实现精确时间同步的协议,特别适用于分布式系统中需要高度协调的操作,比如汽车电子、工业自动化等。 gPTP通过同步主节点(Time Master)和从节点(Time Slave)的时钟,实现全局一致的时间参考。 以下是gPTP实现主从时间同步的详细过程:…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...