关键字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()实现等待/通知的更多相关文章

  1. 12.详解Condition的await和signal等待通知机制

    1.Condition简介 任何一个java对象都天然继承于Object类,在线程间实现通信的往往会应用到Object的几个方法,比如wait(),wait(long timeout),wait(lo ...

  2. Java并发编程,Condition的await和signal等待通知机制

    Condition简介 Object类是Java中所有类的父类, 在线程间实现通信的往往会应用到Object的几个方法: wait(),wait(long timeout),wait(long tim ...

  3. 详解Condition的await和signal等待/通知机制

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  4. object的wait()、notify()、notifyAll()、方法和Condition的await()、signal()方法

    wait().notify()和notifyAll()是 Object类 中的方法 从这三个方法的文字描述可以知道以下几点信息: 1)wait().notify()和notifyAll()方法是本地方 ...

  5. Condition的await()和signal()流程

    介绍 Condition是j.u.c包下提供的一个接口. 可以翻译成 条件对象,其作用是线程先等待,当外部满足某一条件时,在通过条件对象唤醒等待的线程.ArrayBlockingQueue就是通过Co ...

  6. Java并发包源码学习系列:详解Condition条件队列、signal和await

    目录 Condition接口 AQS条件变量的支持之ConditionObject内部类 回顾AQS中的Node void await() 添加到条件队列 Node addConditionWaite ...

  7. 再谈AbstractQueuedSynchronizer:共享模式与基于Condition的等待/通知机制实现

    共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...

  8. 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现

    共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...

  9. Java 并发编程-再谈 AbstractQueuedSynchronizer 2:共享模式与基于 Condition 的等待 / 通知机制实现

    共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...

随机推荐

  1. BZOJ1966: [Ahoi2005]VIRUS 病毒检测 Trie+搜索

    Description 科学家们在Samuel星球上的探险仍在继续.非常幸运的,在Samuel星球的南极附近,探险机器人发现了一个巨大的冰湖!机器人在这个冰湖中搜集到了许多RNA片段运回了实验基地.科 ...

  2. ajax post 参数说明

  3. .Net Core EF Core之Sqlite使用及部署

    1.添加引用Nuget包 Microsoft.EntityFrameworkCore.Sqlite Microsoft.EntityFrameworkCore.Design Microsoft.Ent ...

  4. RN的第一个API-----注册组件Appregistry

    首先解释下AppRegistry是JS运行所有React Native应用的入口  什么是入口? 1.在我们初始化一个react native项目的时候 默认的index.ios.js/index.i ...

  5. Python matplot画柱状图(一)

    图的存在,让数据变得形象化.无论多么复杂的东西,都是简单的组合. import matplotlib.pyplot as plt import numpy as np dict = {'A': 40, ...

  6. shell 跳出循环

    跳出循环 break命令 例: #!/bin/bash while : do echo -n "输入 1 到 5 之间的数字:" read aNum case $aNum in 1 ...

  7. TinyXml节点查找及修改

    参考:http://blog.csdn.net/zww0815/article/details/8083550 // 读者对象:对TinyXml有一定了解的人.本文是对TinyXml工具的一些知识点的 ...

  8. Socket入门之前的知识点

    Socket难点 数据粘包 心跳维持 数据丢包 性能问题 7层网络模型-OSI 基础层:物理层(Physical).数据链路层(Datalink).网络层(Network) 传输层(Transport ...

  9. CentOS Gnome字体不清晰

    需要安装字体:dejavu-sans-mono-fonts The package you need to install is dejavu-sans-mono-fonts. This is the ...

  10. C#中简单的文件操作实例

    using System; using System.IO; namespace Demo { class Program { static string tmpPath = @"D:/Lg ...