• Condition类有很好的灵活性,可以实现多路通知功能,一个Lock对象中可以创建多个Condition对象实例,线程对象可以注册在指定的Condition中,进而有选择的进行线程通知,在调度线程上更加灵活
  • wait与notify/notifyAll进行等待通知时,被通知的线程是随机的,但是Condition与Lock结合的通知是有选择性的通知
  • synchronized就相当于整个Lock对象中只有一个单一的Condition对象,所有线程对象都注册在一个Condition对象身上,线程开始notifyAll时,需要通知所有的WAITING线程,没有选择性,会出现很大的效率问题
 public class MyService {
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void await(){
try {
lock.lock();
System.out.println("await时间为"+System.currentTimeMillis());
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void signal(){
try {
lock.lock();
System.out.println("signal时间为"+System.currentTimeMillis());
condition.signal();
} finally {
lock.unlock();
}
}
}
 public class MyThread extends Thread {
private MyService service; public MyThread(MyService service) {
this.service = service;
} @Override
public void run() {
service.await();
}
}
 public class Run {
public static void main(String[] args) {
try {
MyService service = new MyService();
MyThread mt = new MyThread(service);
mt.start();
Thread.sleep(3000);
service.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

-------------------------------------------------------打印输出-------------------------------------------------------

await时间为1537949157830
signal时间为1537949160830

Condition类中的await方法相当于Object类中的wait方法

Condition类中的signal/signalAll方法相当于Object类中的notify/notifyAll方法

案例2

 public class MyService {
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition(); public void awaitA(){
try {
lock.lock();
System.out.println("begin awaitA时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
condition.await();
System.out.println("end awaitA时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); }
} public void awaitB(){
try {
lock.lock();
System.out.println("begin awaitB时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
condition.await();
System.out.println("end awaitB时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void signalAll(){
try {
lock.lock();
System.out.println("signalAll时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
condition.signalAll();
} finally {
lock.unlock();
}
}
}

线程

 public class ThreadA extends Thread {
private MyService service; public ThreadA(MyService service) {
this.service = service;
} @Override
public void run() {
service.awaitA();
}
}
-------------------------------------------------
public class ThreadB extends Thread {
private MyService service; public ThreadB(MyService service) {
this.service = service;
} @Override
public void run() {
service.awaitB();
}
}
 public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.setName("A");
ThreadB b = new ThreadB(service);
b.setName("B");
a.start();
b.start();
Thread.sleep(3000);
service.signalAll();
}
}

-------------------------------------------------------打印输出-------------------------------------------------------

begin awaitA时间为1537951494924 ThreadName=A
begin awaitB时间为1537951494925 ThreadName=B
signalAll时间为1537951497924 ThreadName=main
end awaitA时间为1537951497924 ThreadName=A
end awaitB时间为1537951497925 ThreadName=B

线程A和B都被唤醒了


使用多个Condition实现通知部分线程

想要单独唤醒部分线程,就需要使用多个Condition对象,先对线程进行分组,Condition对象可以唤醒部分指定线程,有助于提高程序运行效率

 public class MyService {
private Lock lock = new ReentrantLock();
public Condition conditionA = lock.newCondition();
public Condition conditionB = lock.newCondition(); public void awaitA(){
try {
lock.lock();
System.out.println("begin awaitA时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
conditionA.await();
System.out.println("--end awaitA时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void awaitB(){
try {
lock.lock();
System.out.println("begin awaitB时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
conditionB.await();
System.out.println("--end awaitB时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void signAll_A(){
try {
lock.lock();
System.out.println("signAll_A时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
conditionA.signalAll();
} finally {
lock.unlock();
}
} public void signAll_B(){
try {
lock.lock();
System.out.println("signAll_B时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
conditionB.signalAll();
} finally {
lock.unlock();
}
}
}

线程

 public class ThreadA extends Thread {
private MyService service; public ThreadA(MyService service) {
this.service = service;
} @Override
public void run() {
service.awaitA();
}
}
-----------------------------------------------
public class ThreadB extends Thread {
private MyService service; public ThreadB(MyService service) {
this.service = service;
} @Override
public void run() {
service.awaitB();
}
}
 public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.setName("A");
ThreadB b = new ThreadB(service);
b.setName("B");
a.start();
b.start();
Thread.sleep(3000);
service.signAll_A();
}
}

-------------------------------------------------------打印输出-------------------------------------------------------

begin awaitA时间为1537952328573 ThreadName=A
begin awaitB时间为1537952328573 ThreadName=B
signAll_A时间为1537952331572 ThreadName=main
--end awaitA时间为1537952331572 ThreadName=A

线程A被唤醒了,但是线程B仍然在等待

Lock中使用Condition实现等待通知的更多相关文章

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

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

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

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

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

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

  4. Condition实现等待、通知

    使用Condition实现等待/通知: import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.L ...

  5. 十六、Condition等待通知

    一.简介 我们可以使用syncronized和wait,notify实现等待通知.而syncronized的高级实现Lock,也可以实现等待通知,需要构造Condition的实例对象. JDK文档:h ...

  6. Lock接口之Condition接口

    之前在写显示锁的是后,在显示锁的接口中,提到了new Condition这个方法,这个方法会返回一个Condition对象 简单介绍一下 Condition接口: 任意一个Java对象,都拥有一组监视 ...

  7. java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)

    一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.c ...

  8. 显式锁(四)Lock的等待通知机制Condition

       任意一个Java对象,都拥有一组监视器方法(定义在根类Object上),主要包括:wait( ).wait(long timeout).notify().notifyAll()方法:这些方法与关 ...

  9. 使用Condition配合await()和signal()实现等待/通知

    关键字Synchronized与wait()和notify()/notifyAll()结合可以实现“等待/通知”模式, Lock类的子类ReentrantLock也可以实现同样的功能,但需要借助Con ...

随机推荐

  1. YUV/RGB与H264之间的编解码

    1.源码下载 http://download.videolan.org/x264/snapshots/ 2.编译 ./configure --prefix=./_install --enable-sh ...

  2. 作业(二)—python实现wc命令

    Gitee地址:https://gitee.com/c1e4r/word-count(为什么老师不让我们用github) 0x00 前言 好久没发博客了,感觉自己的学习是有点偷懒了.这篇博客也是应专业 ...

  3. Python 第三天学习整理①

    今天学习的内容包括以下几个方面:1.字符编码 2.文件操作 3.函数 1.字符编码 关于字符编码,关注以下几个点 1.1 什么是字符编码 字符编码:字符转化为数字的过程所遵循的标准 字符编码包括:un ...

  4. div标准布局示例

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. ivew-admin 导入excel

    1.使用上传组件 <Upload ref="upload" name="importData" action="/api/device/impo ...

  6. Fiji-imageJ 无法打开

    可能的原因是文件的路径包含中文名称.

  7. rabbitMQ初始化配置

    用户管理添加用户# rabbitmqctl add_user username password删除用户# rabbitmqctl delete_user username修改密码# rabbitmq ...

  8. boost pointer container

    1. boost::ptr_vector #include <boost/ptr_container/ptr_vector.hpp> #include <iostream> i ...

  9. 【Zookeekper】分布锁Curator

    有序节点:假如当前有一个父节点为/lock,我们可以在这个父节点下面创建子节点:zookeeper提供了一个可选的有序特性,例如我们可以创建子节点“/lock/node-”并且指明有序,那么zooke ...

  10. php qq第三方登陆

    0.下载QQ登录(QQ互)php版:下载地址:点击打开链接(本文编写时最新版本:V2.1 ) 1.在QQ互联网站注册一个appid,配置网站地址和回调地址. 例:http://yzdd.app1101 ...