使用Condition配合await()和signal()实现等待/通知
关键字Synchronized与wait()和notify()/notifyAll()结合可以实现“等待/通知”模式,
Lock类的子类ReentrantLock也可以实现同样的功能,但需要借助Condition对象。
优势:在一个Lock对象里面可以创建多个Condition(即对象监视器)实例,
线程对象可以注册在指定的Condition中,从而可以有选择性地对指定线程进行通知,
在调度线程上更加灵活。
实例如下:
需要下面四个类:
封装的业务方法类:MyService.java
线程A类和线程B类:ThreadA.java和ThreadB.java
运行类:Run.java
1、MyService.java
package Condition; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class MyService { private Lock lock = new ReentrantLock(); public Condition conditionA = lock.newCondition();//创建conditionA对象
public Condition conditionB = lock.newCondition();//创建conditionB对象 public void awaitA(){
try{
lock.lock();//事前加lock,保证线程同步,相当于Synchronized作用
System.out.println("begin awaitA:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
conditionA.await();//进入等待,需要被通知才能继续运行下面代码,绑定conditionA对象
System.out.println(" end awaitA:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();//最后不忘unlock()
}
} public void awaitB(){
try{
lock.lock();
System.out.println("begin awaitB:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
conditionB.await();//进入等待,需要被通知才能继续运行下面代码,绑定conditionB对象
System.out.println(" end awaitB:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
} public void signalAll_A(){ try{
lock.lock();
System.out.println(" signalAll_A:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
conditionA.signalAll();//选择性地通知唤醒所有绑定conditionA的对象
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
} } public void signalAll_B(){ try{
lock.lock();
System.out.println(" signalAll_B:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
conditionB.signalAll();//选择性地通知唤醒所有绑定conditionA的对象
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
} } }
2、ThreadA.java
package Condition;
public class ThreadA extends Thread{
private MyService service;
public ThreadA(MyService service){
super();
this.service = service;
}
@Override
public void run(){
service.awaitA();//调用MyService里的awaitA()方法
}
}
3、ThreadB.java
package Condition;
public class ThreadB extends Thread{
private MyService service;
public ThreadB(MyService service){
super();
this.service = service;
}
@Override
public void run(){
service.awaitB();//调用MyService里的awaitB()方法
}
}
4、Run.java
package Condition;
public class Run {
public static void main(String[] args) {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.setName("线程A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("线程B");
b.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
service.signalAll_A();//通知唤醒绑定ConditionA的线程,使其代码继续执行
}
}
使用Condition配合await()和signal()实现等待/通知的更多相关文章
- 12.详解Condition的await和signal等待通知机制
1.Condition简介 任何一个java对象都天然继承于Object类,在线程间实现通信的往往会应用到Object的几个方法,比如wait(),wait(long timeout),wait(lo ...
- Java并发编程,Condition的await和signal等待通知机制
Condition简介 Object类是Java中所有类的父类, 在线程间实现通信的往往会应用到Object的几个方法: wait(),wait(long timeout),wait(long tim ...
- 详解Condition的await和signal等待/通知机制
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...
- object的wait()、notify()、notifyAll()、方法和Condition的await()、signal()方法
wait().notify()和notifyAll()是 Object类 中的方法 从这三个方法的文字描述可以知道以下几点信息: 1)wait().notify()和notifyAll()方法是本地方 ...
- Condition的await()和signal()流程
介绍 Condition是j.u.c包下提供的一个接口. 可以翻译成 条件对象,其作用是线程先等待,当外部满足某一条件时,在通过条件对象唤醒等待的线程.ArrayBlockingQueue就是通过Co ...
- Java并发包源码学习系列:详解Condition条件队列、signal和await
目录 Condition接口 AQS条件变量的支持之ConditionObject内部类 回顾AQS中的Node void await() 添加到条件队列 Node addConditionWaite ...
- 再谈AbstractQueuedSynchronizer:共享模式与基于Condition的等待/通知机制实现
共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...
- 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现
共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...
- Java 并发编程-再谈 AbstractQueuedSynchronizer 2:共享模式与基于 Condition 的等待 / 通知机制实现
共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...
随机推荐
- DD-WRT自定义脚本更新花生壳DDNS
N年以前买了一个tp-link 841n v7,一直用的还算可以吧,除了不定期重启路由器,不然网速慢的龟爬啊!这也是TP原厂固件的通病,于是刷了DD-WRT,话说DD确实很爽,除了功能强大之外,而且很 ...
- Linux 文件的权限
备注 : -rw-r--r-- 第一个“-”不算 ,三个一组 这个就是 644 二.使用chown命令更改文件拥有者 在 shell 中,可以使用chown命令来改变文件所有者.chown命令是c ...
- 【第十八章】 springboot + thymeleaf
代码结构: 1.ThymeleafController package com.xxx.firstboot.web; import org.springframework.stereotype.Con ...
- Vue开发中的中央事件总线
在Vue开发中会遇到大量的组件之间共享数据的情形,针对不同的情形,Vue有相对应的解决方案.比如,父组件向子组件传值可以使用props,复杂项目中不同模块之间传值可以使用Vuex.但是,对于一些简单的 ...
- C#学习笔记(四):switch语句
条件语句 switch语句快速生成枚举方法,复制枚举名在switch()里,双击TAB 快速生成方法,用纠错功能 随机数 using System; using System.Collections. ...
- 03_Spark集群部署
[安装前的环境准备] Hadoop:2.6.1Java:jdk-1.7.0Spark: spark-1.6.0-bin-hadoop2.6.tgzScala: scala-2.11.4.tgz虚拟机: ...
- UVa 10766 Organising the Organisation(矩阵树定理)
https://vjudge.net/problem/UVA-10766 题意: 给出n, m, k.表示n个点,其中m条边不能直接连通,求生成树个数. 思路: 这也算个裸题,把可以连接的边连接起来, ...
- Linux(CentOS 6.5) 下安装MySql 5.7.18 二进制版本粗浅攻略
鉴于Linux和mysql因不同版本,安装方式也不同,所以在阅读本攻略前,请确保各位同学的版本和我的Linux.MySql 版本一致. 如果不一致,只能参考. 我的版本: Linux CentOS 6 ...
- Codeforces Beta Round #17 A.素数相关
A. Noldbach problem Nick is interested in prime numbers. Once he read about Goldbach problem. It sta ...
- jenkins 插件,下载地址
http://updates.jenkins-ci.org/download/plugins/ 通常我们需要下载的插件有如下几个: