聊聊Condition
本文可作为传智播客《张孝祥-Java多线程与并发库高级应用》的学习笔记。
上面我们说了Lock,那是对synchronized的一种更为面向对象的替代,在原来的synchronized内部,我们可以调用object的wait与notify方法,那么使用lock之后,如何进行线程的通信呢。
对锁不清楚的朋友可以看看
http://blog.csdn.net/dlf123321/article/details/42919085
答案是condition。
condition一方面是对lock功能的补充(也就是说,你用了lock,为了保证线程的通信,就得用condition)
另一方面,synchronized的notifyall是唤醒所有等待的线程,那么如果有些线程我不想唤醒呢。
看下面这个例子
主线程运行10次,然后子线程2运行20次,接着子线程3运行30次
上面的整体运行4次。
我们分析一下,主线程运行10次之后,下面一方面让自己阻塞,同时应该唤醒子线程2,并且不能唤醒子线程3。
如果用notifyAll就等于把线程2与线程3都唤醒了。
我们在这里说明一下
Reentrantlock相比较于synchronized还少有三个优势
1 等待可中断 具体的例子参考 http://uule.iteye.com/blog/1488356
2 实现公平锁 就是线程a在操作某个对象,线程b,c,d后面又依次来了,如果是非公平锁,那么等a结束后,bcd接手的概率是一样的,如果是公平锁那么a完了之后就是b
synchronized是非公平的是,Reentrantlock默认情况下也是非公平的,但可以通过有带Boolean只的构造函数构建一个公平锁
3 绑定多个条件 也就是下面讲的
4 有三种使用方式
a) lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
c)tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
参考资料 http://houlinyan.iteye.com/blog/1112535
另外我得说明一点
就性能来说,在java6之后,reentrantlock与synchronized已经差不多了
而且Reentrantlock得主动释放
所有到底选择哪个实现互斥,大家还是得考虑一下
看看方法
常用的就是await与signal。
这个两个就刚好对应object的wait与notify。
我们看代码:
package cn.itcast.heima2;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreeConditionCommunication {
/**
* @param args
*/
public static void main(String[] args) {
final Business business = new Business();
new Thread(
new Runnable() {
@Override
public void run() {
for(int i=1;i<=4;i++){
business.sub2(i);
}
}
}
).start();
new Thread(
new Runnable() {
@Override
public void run() {
for(int i=1;i<=4;i++){
business.sub3(i);
}
}
}
).start();
for(int i=1;i<=4;i++){
business.main(i);
}
}
static class Business {
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
private int shouldSub = 1;
public void sub2(int i){
lock.lock();
try{
while(shouldSub != 2){
try {
condition2.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=1;j<=20;j++){
System.out.println("sub2 thread sequence of " + j + ",loop of " + i);
}
shouldSub = 3;
condition3.signal();
}finally{
lock.unlock();
}
}
public void sub3(int i){
lock.lock();
try{
while(shouldSub != 3){
try {
condition3.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=1;j<=30;j++){
System.out.println("sub3 thread sequence of " + j + ",loop of " + i);
}
shouldSub = 1;
condition1.signal();
}finally{
lock.unlock();
}
}
public void main(int i){
lock.lock();
try{
while(shouldSub != 1){
try {
condition1.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=1;j<=10;j++){
System.out.println("main thread sequence of " + j + ",loop of " + i);
}
shouldSub = 2;
condition2.signal();
}finally{
lock.unlock();
}
}
}
}
聊聊Condition的更多相关文章
- ReentrantReadWriteLock读写锁的使用1
本文可作为传智播客<张孝祥-Java多线程与并发库高级应用>的学习笔记. 一个简单的例子 两个线程,一个不断打印a,一个不断打印b public class LockTest { publ ...
- 聊聊高并发(十四)理解Java中的管程,条件队列,Condition以及实现一个堵塞队列
这篇里面有一些主要的概念,理解概念是件有意义的事情,仅仅有理解概念才干在面对详细问题的时候找到正确的解决思路.先看一下管程的概念 第一次在书上看到管程这个中文名称认为非常迷糊,管程究竟是个什么东东,于 ...
- 聊聊并发(七)——Java中的阻塞队列
3. 阻塞队列的实现原理 聊聊并发(七)--Java中的阻塞队列 作者 方腾飞 发布于 2013年12月18日 | ArchSummit全球架构师峰会(北京站)2016年12月02-03日举办,了解更 ...
- 聊聊高并发(十八)理解AtomicXXX.lazySet方法
看过java.util.concurrent.atomic包里面各个AtomicXXX类实现的同学应该见过lazySet方法.比方AtomicBoolean类的lazySet方法 public fin ...
- 聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁
这篇讲讲ReentrantReadWriteLock可重入读写锁,它不仅是读写锁的实现,而且支持可重入性. 聊聊高并发(十五)实现一个简单的读-写锁(共享-排他锁) 这篇讲了怎样模拟一个读写锁. 可重 ...
- 并发王者课-铂金6:青出于蓝-Condition如何把等待与通知玩出新花样
欢迎来到<[并发王者课](https://juejin.cn/post/6967277362455150628)>,本文是该系列文章中的**第19篇**. 在上一篇文章中,我们介绍了阻塞队 ...
- 聊聊Unity项目管理的那些事:Git-flow和Unity
0x00 前言 目前所在的团队实行敏捷开发已经有了一段时间了.敏捷开发中重要的一个话题便是如何对项目进行恰当的版本管理.项目从最初使用svn到之后的Git One Track策略再到现在的GitFlo ...
- Mono为何能跨平台?聊聊CIL(MSIL)
前言: 其实小匹夫在U3D的开发中一直对U3D的跨平台能力很好奇.到底是什么原理使得U3D可以跨平台呢?后来发现了Mono的作用,并进一步了解到了CIL的存在.所以,作为一个对Unity3D跨平台能力 ...
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.c ...
随机推荐
- hdu 5491(位运算)
题意:给你n,a,b. 希望得到比n大,二进制1的个数在 a ,b之间的最小的数 思路:①满足条件,输出 ②num < a 从右找到是0的最小位,变成1 ③num > b从右到左找是1的最 ...
- HDU 1540 Tunnel Warfare(最长连续区间 基础)
校赛,还有什么途径可以申请加入ACM校队? Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/ ...
- python变量、条件循环语句
1. 变量名 - 字母 - 数字 - 下划线 #数字不能开头:不能是关键字:最好不好和python内置的函数等重复 2. 条件语句 缩进用4个空格(Tab键)注意缩进如果是空格键和Tab键混用, ...
- python2.7练习小例子(二)
2):题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%:2 ...
- struts2 Action获取表单传值(属性,类))
http://blog.csdn.net/sd0902/article/details/8393157 求大神告知两种方法的不同点 都是写个set方法就行了
- 【DDD】--好文收藏
发现一批好文,完整系列,攒~~ 随笔分类 - DDD - 『圣杰』 DDD理论学习系列(1)-- 通用语言 笔记: 通用语言: a) 简单,便于理解.传播. b) 需要通用,能够准确的传达业务规则. ...
- OpenCV设置摄像头分辨率及全屏显示
OpenCV3.0下 设置摄像头分辨率为1920*1440,并全屏显示图像窗口. int _tmain(int argc, _TCHAR* argv[]) { Mat frame; VideoCapt ...
- JS实现2048代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- ES6(类)
类的概念 1.基本定义 2.继承 继承如何传递参数?(super) 定义自己属性的时候调用 this 一定要在 super 之后(在继承关系中,子类的构造函数如果用 super 传递参数的过程中,su ...
- SpringMVC之拦截器实现登录验证
今天回头看之前发的javaweb学习路线图,发现把路线图中的也学的有一半多了,不过还是路漫漫.在前面的博客中有学习过spring的aop,它利用动态代理实现,在springmvc中也是一样,今天使用H ...