使用ReentrantLock中的条件变量让多个线程顺序执行
一. 前言
近日一个学生在参加某公司校招面试时,遇到一个多个线程顺序执行的面试题,特意记录下来和大家分享一下,这个题目的具体要求是这样的:
假设有3个线程 a,b,c,要求三个线程一起进入到就绪态,执行时一定要按照 a-->b-->c的顺序执行。即使a或者b线程进入到了阻塞态,也一定会按照a-->b-->c的顺序运行线程。请问该如何保证实现这个需求呢?
二. 解决方案
关于这道题,百度一下网上常见的实现思路,大致有4种解决方案:
- 通过join()方法使当前线程“阻塞”,等待指定线程执行完毕后继续执行;
- 通过倒数计时器CountDownLatch实现;
- 通过创建单一化线程池 newSingleThreadExecutor()实现;
- 通过ReentrantLock 中的条件变量实现;
今天先使用ReentrantLock 的条件变量来实现这个题目中的需求。
三. 使用ReentrantLock 条件变量
首先咱们来了解一下,什么是ReentrantLock 条件变量(Condition)。
ReentrantLock 中的条件变量功能,类似于普通 synchronized 的 wait、notify,我们可以使用Reentrantlock 锁,配合 Condition 对象上的 await()和 signal()或 signalAll()方法,来实现线程间协作。与synchronized的wait和notify不同之处在于,ReentrantLock中的条件变量可以有多个,可以实现更精细的控制线程。
Condition中常用的方法API有如下这些:
ReentrantLock代码实现:
代码执行效果如下图:
现在我们就会发现,3个线程已经可以被随意控制了,你会了吗?
如上文所述,让多个线程按顺序执行,网上常见的解决方案有4种。但大家要注意的是,面试官出这个题有一个先决条件,“要让所有的线程同时就绪”,所以我们就可以排除使用join方法和使用单一化线程池的方案了。那么要想实现这个面试题中的需求,比较靠谱的方法只剩下ReentrantLock 中的条件变量和使用倒数计时器CountDownLatch两种方案了。
相关推荐HOT
更多>>如何添加Java环境变量?
要添加Java环境变量,可以按照以下步骤:并安装Java开发工具包(JDK)、找到Java安装路径、设置JAVA_HOME环境变量、添加Java可执行文件路径到PATH...详情>>
2023-05-04 11:00:56从零开始学Java之String字符串的编码
对很多小白来说,可能不明白什么是字符编码,也不知道为什么要有字符编码,所以先来给大家简要地介绍一下字符编码。详情>>
2023-05-04 10:21:02新手速来!几步带你掌握MyBatis Plus
Mybatis-Plus(简称MP)是一款Mybatis的增强工具,它是在Mybatis的基础上实现的简化开发工具。Mybatis-Plus给我们提供了开箱即用的CRUD操作、自动...详情>>
2023-04-28 10:57:09学习java需要什么基础?基础知识有哪些?
网络编程:了解基本的网络编程概念和协议,熟悉 Java 网络编程 API。建议在学习 Java 之前,先学习一些基础的编程语言,如 C 或 Python 等,这...详情>>
2023-04-28 10:41:14