通过一道面试题了解Condition线程通信
Condition
- Condition接口描述了可能会与锁有关联的条件变量。这些变量在用法与使用Object.wait访问的隐式监视器类似,但提供了更强大的功能。需要特别指出的是,单个Lock可能与多个Condition对象关联。为了避免兼容性问题,Condition方法的名称与对应的Object版本中的不同;
- 在Condition对象中,与wait、notify和notifyAll方法对应的分别是await、signal和signalAll;
- Condition实例实质上被绑定到一个锁上。要为特定Lock实例获得Condition实例,请使用器newCondition()方法。
面试题
package com.ccfdod.juc; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* 题目:编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。
* 如:ABCABCABC……
*/
class AlternateDemo {
//标志当前由哪一个线程输出,1代表A,2代表B,3代表C
private int number = 1; Lock lock = new ReentrantLock(); //Condition的强大之处在于它可以为多个线程间建立不同的Condition
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition(); // loopNum:当前循环轮数
public void loopA(int loopNum) {
//上锁
lock.lock();
try {
while (number != 1) {
//等待
condition1.await();
} System.out.println(Thread.currentThread().getName() + ", currentLoopNum is " + loopNum);
number = 2;
//唤醒
condition2.signal(); } catch (InterruptedException e) {
e.printStackTrace();
} finally {
//确保释放锁
lock.unlock();
}
} public void loopB(int loopNum) {
lock.lock();
try {
while (number != 2) {
condition2.await();
} System.out.println(Thread.currentThread().getName() + ", currentLoopNum is " + loopNum);
number = 3;
condition3.signal(); } catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void loopC(int loopNum) {
lock.lock();
try {
while (number != 3) {
condition3.await();
} System.out.println(Thread.currentThread().getName() + ", currentLoopNum is " + loopNum);
number = 1;
condition1.signal(); } catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
} public class TestABCAlternate { public static void main(String[] args) {
AlternateDemo ad = new AlternateDemo(); new Thread(new Runnable() { @Override
public void run() {
for (int i = 0; i < 10; i++)
ad.loopA(i);
}
}, "A").start(); new Thread(new Runnable() { @Override
public void run() {
for (int i = 0; i < 10; i++)
ad.loopB(i);
}
}, "B").start(); new Thread(new Runnable() { @Override
public void run() {
for (int i = 0; i < 10; i++)
ad.loopC(i);
}
}, "C").start();
}
}
通过一道面试题了解Condition线程通信的更多相关文章
- Condition线程通信(七)
前言:对于线程通信,使用synchronized时使用wait.notify和notifyAll来实行线程通信.而使用Lock如何处理线程通信呢?答案就是本片的主角:Condition. 一.Cond ...
- java 多线程 day13 condition 线程通信
/** * Created by chengtao on 17/12/5. * Condition 类似 wait和notify,解决线程间的同步问题 */ import java.util.conc ...
- 一道面试题来了解线程notifyAll()和wait()的方法
题目:三个线程,分别打印A.B.C,要求按ABC的顺序循环打印10次. package com.slowcity.crud.controller; public class PrintOneTwoTh ...
- Condition线程通信_生产者消费者案例
①Condition 接口描述了可能会与锁有关联的条件变量. 这些变量在用 法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的 功能. 需要特别指出的是,单个 Lock 可能与 ...
- JAVA多线程提高二:传统线程的互斥与同步&传统线程通信机制
本文主要是回顾线程之间互斥和同步,以及线程之间通信,在最开始没有juc并发包情况下,如何实现的,也就是我们传统的方式如何来实现的,回顾知识是为了后面的提高作准备. 一.线程的互斥 为什么会有线程的互斥 ...
- JAVA基础知识之多线程——线程通信
传统的线程通信 Object提供了三个方法wait(), notify(), notifyAll()在线程之间进行通信,以此来解决线程间执行顺序等问题. wait():释放当前线程的同步监视控制器,并 ...
- Java核心知识点学习----使用Condition控制线程通信
一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...
- 多线程之线程通信条件Condition
Condition是Locks锁下的还有一种线程通信之间唤醒.堵塞的实现.它以下的await,和signal可以实现Object下的wait,notify和notifyAll的所有功能,除此之外改监视 ...
- Condition控制线程通信
Condition控制线程通信 一.前言 java.util.concurrent.locks.Condition 接口描述了可能会与锁有关联的条件变量.这些变量在用法上与使用Object.wait ...
随机推荐
- quartz (一) 基于 Quartz 开发企业级任务调度应用
本文转自:http://www.ibm.com/developerworks/cn/opensource/os-cn-quartz/ Quartz 基本概念及原理 Quartz Scheduler 开 ...
- Web服务器实现文件传输程序设计
总体概括来说就是设计一个Web服务器的流程,将执行流程分为简单的步骤,每个步骤作为一个模块来实现. 1.整体设计 服务器程序发送文件给客户端或者从客户端接收文件,每次通信只能做一次文件传输,传输完毕后 ...
- zookeeper curator客户端之增删改查
zookeeper curator客户端之增删改查 zookeeper安装:https://www.cnblogs.com/zwcry/p/10272506.html curator客户端是Apach ...
- Linux中find
Linux中find常见用法示例 ·find path -option [ -print ] [ -exec -ok command ] {} \; find命令的参数 ...
- webservice使用方法
1,右击项目选择-->添加服务引用: 填写一个 命名空间名称; 2, 实例化 命名空间名称 ; 选择 带client的服务名称进行初始化 3,开始调用方法 // 带参数的webservice ...
- Activiti:创建activiti工程
Activiti:创建activiti工程 一.Activiti下载: 1,Activiti下载地址:https://github.com/Activiti/Activiti/releases 2,A ...
- 生产者消费者JAVA实现
三种实现方式: 1. Object对象的wait(),notify(),加synchronize. 2. Lock的await(),signal(). 3. BlockingQueue阻塞队列. Ob ...
- Fiddler4调试工具配置使用笔记
Fiddler最大的用处: 模拟请求.修改请求.手机应用调试 Fiddler最新版本 下载地址: http://www.telerik.com/download/fiddler Fiddler 想要监 ...
- keras安装配置指南【linux环境】【转】
本文转载自:https://keras-cn.readthedocs.io/en/latest/for_beginners/keras_linux/#kerasmnist 本教程不得用于任何形式的商业 ...
- jz2440使用openjtag+openocd+eclipse调试【学习笔记】
平台:jz2440 作者:庄泽彬(欢迎转载,请注明作者) 说明:韦东山二期视频学习笔记 交叉编译工具:arm-linux-gcc (GCC) 3.4.5 eclipse版本:eclipse-cpp-l ...