文档章节

java并发控制:ReentrantLock Condition使用详解

张升强
 张升强
发布于 2015/06/16 14:11
字数 553
阅读 3.6K
收藏 16

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

我们通过一个实际的例子来解释Condition的用法:

我们要打印1到9这9个数字,由A线程先打印1,2,3,然后由B线程打印4,5,6,然后再由A线程打印7,8,9. 这道题有很多种解法,现在我们使用Condition来做这道题(使用Object的wait,notify方法的解法在这里)。

package cn.xband.locks;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test{
	static class NumberWrapper {
		public int value = 1;
	}

	public static void main(String[] args) {
		//初始化可重入锁
		final Lock lock = new ReentrantLock();
		
		//第一个条件当屏幕上输出到3
		final Condition reachThreeCondition = lock.newCondition();
		//第二个条件当屏幕上输出到6
		final Condition reachSixCondition = lock.newCondition();
		
		//NumberWrapper只是为了封装一个数字,一边可以将数字对象共享,并可以设置为final
		//注意这里不要用Integer, Integer 是不可变对象
		final NumberWrapper num = new NumberWrapper();
		//初始化A线程
		Thread threadA = new Thread(new Runnable() {
			@Override
			public void run() {
				//需要先获得锁
				lock.lock();
				try {
					System.out.println("threadA start write");
					//A线程先输出前3个数
					while (num.value <= 3) {
						System.out.println(num.value);
						num.value++;
					}
					//输出到3时要signal,告诉B线程可以开始了
					reachThreeCondition.signal();
				} finally {
					lock.unlock();
				}
				lock.lock();
				try {
					//等待输出6的条件
					reachSixCondition.await();
					System.out.println("threadA start write");
					//输出剩余数字
					while (num.value <= 9) {
						System.out.println(num.value);
						num.value++;
					}

				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					lock.unlock();
				}
			}

		});


		Thread threadB = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					lock.lock();
					
					while (num.value <= 3) {
						//等待3输出完毕的信号
						reachThreeCondition.await();
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					lock.unlock();
				}
				try {
					lock.lock();
					//已经收到信号,开始输出4,5,6
					System.out.println("threadB start write");
					while (num.value <= 6) {
						System.out.println(num.value);
						num.value++;
					}
					//4,5,6输出完毕,告诉A线程6输出完了
					reachSixCondition.signal();
				} finally {
					lock.unlock();
				}
			}

		});


		//启动两个线程
		threadB.start();
		threadA.start();
	}
}



上述代码中有完整的注释,请参考注释,理解Condition的用法。

基本思路就是首先要A线程先写1,2,3,这时候B线程应该等待reachThredCondition信号,而当A线程写完3之后就通过signal告诉B线程“我写到3了,该你了”,这时候A线程要等嗲reachSixCondition信号,同时B线程得到通知,开始写4,5,6,写完4,5,6之后B线程通知A线程reachSixCondition条件成立了,这时候A线程就开始写剩下的7,8,9了。

© 著作权归作者所有

张升强
粉丝 39
博文 119
码字总数 154023
作品 0
广州
高级程序员
私信 提问
加载中

评论(1)

xingkong513
xingkong513
这个例子是有bug
假如定义线程A的第一个lock为AL1,第二个为AL2,
线程B的也一样,BL1、BL2

执行顺序AL1、BL1一定先于AL2、BL2,
AL1、BL1哪个先都无所谓,因为在BL1中await是有num.value <= 3的判断,
但是AL2、BL2的执行顺序在例子中就必须为AL2先于BL2获取lock,否则线程会一直卡住,
如果要正常跑完,BL2需要判断num.value == 4时await(等于7时不wait)
整理了一些博主的JAVA系列----列成目录方便学习

一.深入理解计算机系统(博主 YSOcean) 深入理解计算机系统(序章) Hello World 是如何运行的 存储设备 操作系统的抽象概念 汇编语言和机器语言 程序编码以及数据格式 操作数指示符和数据传送...

osc_gk4k1cnl
2019/03/22
6
0
最强Java并发编程详解:知识点梳理,BAT面试题等

本文原创,更多内容可以参考: Java 全栈知识体系。如需转载请说明原处。 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解并发...

osc_agn9pfb0
04/16
16
0
Java多线程并发07——锁在Java中的实现

上一篇文章中,我们已经介绍过了各种锁,让各位对锁有了一定的了解。接下来将为各位介绍锁在Java中的实现。关注我的公众号「Java面典」了解更多 Java 相关知识点。 在 Java 中主要通过使用s...

osc_o60il3e6
04/16
4
0
Java并发编程-ReentrantLock

  上文已经总结了AQS的前世今生,有了这个基础我们就可以来进一步学习并发工具类。首先我们要学习的就是ReentrantLock,本文将从ReentrantLock的产生背景、源码原理解析和应用来学习Reent...

osc_iqtexsjp
2018/08/25
4
0
Java多线程系列——从菜鸟到入门

持续更新系列。 参考自Java多线程系列目录(共43篇)、《Java并发编程实战》、《实战Java高并发程序设计》、《Java并发编程的艺术》。 基础 Java多线程系列——过期的suspend()挂起、resume()继...

郑斌blog
2017/02/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

python+selenium自动化框架搭建

很多人想要项目源码之前都是加我QQ之后一个一个发的,这样有点麻烦,所以我就建了一个群,完整的项目文件放在里面了有需要的直接加这个群,其他的资料我也会放在里面。群里都是一些学习自动化...

osc_twlari2q
31分钟前
14
0
Dash 5 for Mac 5.1.6 好用的API文档工具

Dash for mac是使用与Mac OS平台的软件编程文档管理工具,Dash 5 Mac破解版可以浏览API文档,以及管理代码片段工具。Dash自带了丰富的API文档,涉及各种主流的编程语言和框架。 Dash是一个A...

麦克W
33分钟前
11
0
关于百度地图js api的getCurrentPosition定位不准确的解决方法

很久之前帮大叔解决了一个gps坐标转换为百度地图坐标的问题。今天大叔又给我讲百度地图定位不准。我查了一下api,用了官方给出的这样一组函数。 1 //创建查询对象 2 var geolocation = ne...

osc_wl6d9wri
33分钟前
18
0
12章节 Samba、NFS文件共享服务 13章节 bind域名解析服务

12.1 SAMBA文件共享服务 FTP文件传输服务确实可以让主机之间的文件传输变得简单方便,但是FTP协议的本质是传输文件,而非共享文件。 1991年,当时还在读大学的Tridgwell,为了解决Linux系统与...

bpqd2020
33分钟前
8
0
XGBoost 重要参数(调参使用)

XGBoost 重要参数(调参使用) 数据比赛Kaggle,天池中最常见的就是XGBoost和LightGBM。 模型是在数据比赛中尤为重要的,但是实际上,在比赛的过程中,大部分朋友在模型上花的时间却是相对较少的...

osc_kedi1mvz
34分钟前
28
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部