Condition

一、Condition概述

在线程的同步时可以使一个线程阻塞而等待一个信号,同时放弃锁使其他线程可以能竞争到锁。

在synchronized中我们可以使用Object的wait()和notify方法实现这种等待和唤醒。

在Lock可以实现相同的功能就是通过Condition。Condition中的await()和signal()/signalAll()就相当于Object的wait()和notify()/notifyAll()。

除此之外,Condition还是对多线程条件进行更精确的控制。notify()是唤醒一个线程,但它无法确认是唤醒哪一个线程。 但是,通过Condition,就能明确的指定唤醒读线程。

二、Condition和Object案例对比

案例说明:生成者在仓库满时,进入等待状态,同时唤醒消费者线程,消费者在仓库为空时,进入等待。同时唤醒生产者线程。

1、采用await()和signal()方式

(1)测试类

public class ConditionLockTest {

    public static void main(String[] args){

        //相当于仓库
Depot depot=new Depot(); //创建两个生产者一个消费者
Producer producer1=new Producer(depot);
Producer producer2=new Producer(depot);
Consumer consumer1=new Consumer(depot); //采用线程池方式
Executor executors=Executors.newFixedThreadPool(5);
executors.execute(producer1);
executors.execute(producer2);
executors.execute(consumer1);
}
} //生产者
class Producer implements Runnable { Depot depot;
public Producer(Depot depot){
this.depot=depot;
}
public void run(){
while(true){
depot.prod();
}
}
} //消费者
class Consumer implements Runnable{ Depot depot;
public Consumer(Depot depot){
this.depot=depot;
}
public void run(){
while(true){
depot.consum();
}
}
}

(2)仓库类

public class Depot {
//初始仓库为0,最大为10,超过10生产者停止生产
private int size;
private int maxSize=10; private Condition prodCondition;
private Condition consumCondition; private Lock lock;
public Depot(){ this.size=0;
this.lock=new ReentrantLock();
//可以看出Condition对象依赖于Lock锁
this.prodCondition=this.lock.newCondition();
this.consumCondition=this.lock.newCondition();
} /*
* 生产者生产方法
*/
public void prod(){ lock.lock();
try{
//如果生产超过max值,则生产者进入等待
while(size+1>maxSize){
try {
System.out.println(Thread.currentThread().getName()+"生产者进入等待状态");
prodCondition.await();
} catch (Exception e) {
e.printStackTrace();
}
}
size+=1;
System.out.println(Thread.currentThread().getName()+" 生产了一个 "+1+" 总共还有 "+size); //唤醒消费者线程
consumCondition.signal(); }finally {
lock.unlock();
}
} /*
* 消费者消费方法
*/
public void consum(){ lock.lock();
try{
//如果当前大小减去要消费的值,如果小于0的话,则进入等待
while(size-1<0){
try {
System.out.println(Thread.currentThread().getName()+" 消费者进入等待状态");
consumCondition.await(); } catch (Exception e) {
e.printStackTrace();
}
} size-=1;
System.out.println(Thread.currentThread().getName()+" 消费者消费了 "+1+" 个,总共还有 "+size);
//唤醒生产者线程
prodCondition.signal();
}finally {
lock.unlock();
}
}
}

运行结果(截取部分图)

根据结果分析可以得出:
      生产者生产产品,当超过10个,生产者会处于等待状态,直到消费者消费者消费了一个产品,生产者才会重新唤醒。

2、采用wait()和notifyAll()方法

 (1)仓库类代码(测试类代码不变)

public class Depot {
//初始仓库为0,最大为10,超过10生产者停止生产
private int size;
private int maxSize=10; public Depot(){
this.size=0;
} /*
* 生产者生产方法
*/
public synchronized void prod(){ try{
//如果生产超过max值,则生产者进入等待
while(size+1>maxSize){
try {
//采用wait方法
wait();
System.out.println(Thread.currentThread().getName()+"生产者进入等待状态");
} catch (Exception e) {
e.printStackTrace();
}
} size+=1;
System.out.println(Thread.currentThread().getName()+" 生产了一个 "+1+" 总共还有 "+size); //唤醒所有线程
notifyAll(); }finally {
}
} /*
* 消费者消费方法
*/
public synchronized void consum(){ try{
//如果当前大小减去要消费的值,如果小于0的话,则进入等待
while(size-1<0){
try {
wait();
System.out.println(Thread.currentThread().getName()+" 消费者进入等待状态"); } catch (Exception e) {
e.printStackTrace();
}
} size-=1;
System.out.println(Thread.currentThread().getName()+" 消费者消费了 "+1+" 个,总共还有 "+size);
//唤醒所有线程
notifyAll(); }finally {
}
}
}

运行结果:

对比:

首先可以看出两个都可以实现生产者消费者的工作,不过可以发现Condition的signal相对于Object的notify最大有点就是它可以唤醒指定的线程,

比如这里可以指定唤醒生产线程或者消费线程,而用notify是不能唤醒指定线程的,你只能通过notifyAll来唤醒所有。

想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。少校【14】

java多线程(7)---Condition的更多相关文章

  1. Java多线程——Lock&Condition

    Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. package ...

  2. java 多线程 day13 condition 线程通信

    /** * Created by chengtao on 17/12/5. * Condition 类似 wait和notify,解决线程间的同步问题 */ import java.util.conc ...

  3. 玩转Java多线程(Lock.Condition的正确使用姿势)

    转载请标明博客的地址 本人博客和github账号,如果对你有帮助请在本人github项目AioSocket上点个star,激励作者对社区贡献 个人博客:https://www.cnblogs.com/ ...

  4. Java多线程系列--“JUC锁”06之 Condition条件

    概要 前面对JUC包中的锁的原理进行了介绍,本章会JUC中对与锁经常配合使用的Condition进行介绍,内容包括:Condition介绍Condition函数列表Condition示例转载请注明出处 ...

  5. Java多线程——Condition条件

    简介 Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signa ...

  6. Java多线程(九)之ReentrantLock与Condition

    一.ReentrantLock 类   1.1 什么是reentrantlock   java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 ...

  7. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...

  8. Java多线程系列--“JUC锁”04之 公平锁(二)

    概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...

  9. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例

    概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...

  10. Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock

    本章对ReentrantLock包进行基本介绍,这一章主要对ReentrantLock进行概括性的介绍,内容包括:ReentrantLock介绍ReentrantLock函数列表ReentrantLo ...

随机推荐

  1. dos choice 命令

    dos choice 命令 choice /c YNC /m "Are you sure?" if %errorlevel%==1 goto Y if %errorlevel%== ...

  2. ISP PIPLINE (十二) Sharpening

    什么是sharpening? 不解释,从左到右为sharpen , 从右到左为blur. 简单理解为边缘增强,使得轮廓清晰.增强对比度. 如何进行sharpening? 下面是实际sharpen的过程 ...

  3. 2018-2019-2 网络对抗技术 20162329 Exp3 免杀原理与实践

    目录 免杀原理与实践 一.基础问题回答 1.杀软是如何检测出恶意代码的? 2.免杀是做什么? 3.免杀的基本方法有哪些? 二.实验内容 1. 正确使用msf编码器 2. msfvenom生成如jar之 ...

  4. python可视化库 Matplotlib 00 画制简单图像

    1.下载方式:直接下载Andaconda,简单快捷,减少准备环境的时间 2.图像 3.代码:可直接运行(有详细注释) # -*- encoding:utf-8 -*- # Copyright (c) ...

  5. user-agent | what is the "user-agent" ?

    User Agent(用户代理) UA是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本.CPU 类型.浏览器及版本.浏览器渲染引擎.浏览器语言.浏览器插件等 通过抓包可以得到 下面是几个 ...

  6. banner | what is the "banner" ?

    banner/横幅   获取 banner(横幅) 信息属于信息搜集   因为在 banner 信息中,可以获取到软件开发商.软件名称.服务类型.版本号等   而版本号有时候就会存在公开的 CVE 问 ...

  7. Android 第四次作业

    一.团队成员: 段嗣跃:https://www.cnblogs.com/duansiyue/ 陈素伟:https://www.cnblogs.com/aX-qhu/ 二.APK链接: https:// ...

  8. AWSS3异步等待上传成功返回结果

    /// <summary> /// 流上传文件 /// </summary> /// <param name="data">流内容</pa ...

  9. 自定义类在PropertyGrid上的展示方法

    自定义类在PropertyGrid上的展示方法 零.引言 PropertyGrid用来显示某一对象的属性,但是并不是所有的属性都能编辑,基本数据类型(int, double等)和.Net一些封装的类型 ...

  10. js 事件模型详解

    把js的事件模型,分为两类,DOM0级和DOM2级, DOM0级 通常直接在DOM对象上绑定函数对象,指定事件类型,dom.onClick = function(){};类似于这种写法,移除事件,则直 ...