多线程-Condition
关键字synchronized与wait和notify/notifyAll方法相结合可以实现等待/通知模式,类ReentrantLock也可以实现同样的功能,但需要借助于Condition对象。Condition类是JDK5中出现的技术,使用它有更好的灵活性,比如可以实现多路通知功能,也就是在一个Lock对象里面可以创建多个Condition(即对象监视器)实例,线程对象可以注册在指定的Condition中,从而可以有选择性地进行线程通知,在调度线程上更加灵活。
在使用notify/notifyAll方法进行通知时,被通知的线程却是由JVM随机选择的。但使用ReentrantLock结合Condition类是可以实现前面介绍过的“选择性通知”,这个功能是非常重要的,而且在Condition类中是默认提供的。
而synchronized就相当于整个Lock对象中只有一个单一的Condition对象,所有的线程都注册到它一个对象的身上。线程开始notifyAll时,需要通知所有的WAITING线程,没有选择权,会出现相当大的效率问题。
package org.github.lujiango; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Test06 { static class Service {
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition(); public void await() {
try {
lock.lock();
System.out.println("await time: " + System.currentTimeMillis());
condition.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void signal() {
try {
lock.lock();
System.out.println("signal time: " + System.currentTimeMillis());
condition.signal();
} finally {
lock.unlock();
}
}
} static class ThreadA extends Thread {
private Service service; public ThreadA(Service service) {
this.service = service;
} @Override
public void run() {
service.await();
}
} public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.start();
Thread.sleep(3000);
service.signal();
}
}
如果想单独唤醒部分线程该怎么处理呢?这时就有必要使用多个Condition对象了,也就是Condition对象可以唤醒部分指定线程,有助于提升程序运行的效率。可以先对线程进行分组,然后在唤醒指定组中的线程。
package org.github.lujiango; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Test07 { static class MyService {
private Lock lock = new ReentrantLock();
public Condition condition1 = lock.newCondition();
public Condition condition2 = lock.newCondition(); public void await1() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + " begin await1");
condition1.await();
System.out.println(Thread.currentThread().getName() + " end await1");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void await2() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + " begin await2");
condition2.await();
System.out.println(Thread.currentThread().getName() + " end await2");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void signalAll1() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + " signalAll1");
condition1.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void signalAll2() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + " signalAll2");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} } static class ThreadA extends Thread {
private MyService service; public ThreadA(MyService service) {
this.service = service;
} @Override
public void run() {
service.await1();
}
} static class ThreadB extends Thread {
private MyService service; public ThreadB(MyService service) {
this.service = service;
} @Override
public void run() {
service.await2();
}
} public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
Thread.sleep(3000);
service.signalAll2();
} }
实现生产者/消费者模式:一对一交替打印
package org.github.lujiango; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Test08 { static class Service {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private Boolean hasValue = Boolean.FALSE; public void producer() {
try {
lock.lock();
while (hasValue) {
condition.await();
}
System.out.println("producer");
hasValue = Boolean.TRUE;
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void consumer() {
try {
lock.lock();
while (!hasValue) {
condition.await();
}
System.out.println("consumer");
hasValue = Boolean.FALSE;
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} } static class ThreadA extends Thread {
private Service service; public ThreadA(Service service) {
this.service = service;
} @Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
service.producer();
}
}
} static class ThreadB extends Thread {
private Service service; public ThreadB(Service service) {
this.service = service;
} @Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
service.consumer();
}
}
} public static void main(String[] args) {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.start();
ThreadB b = new ThreadB(service);
b.start();
} }
多线程-Condition的更多相关文章
- java多线程-Condition
Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set ...
- Java多线程——Condition条件
简介 Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signa ...
- Java多线程Condition定点通知
多线程之间按顺序调用,实现A->B->C三个线程启动,要求如下:A打印5次,B打印10次,C打印15次接着 A打印5次,B打印10次,C打印15次 来10轮 package com.yan ...
- Python 多线程 Condition 的使用
Condition Condition(条件变量)通常与一个锁关联.需要在多个Contidion中共享一个锁时,可以传递一个Lock/RLock实例给构造方法,否则它将自己生成一个RLock实例. 可 ...
- python多线程--Condition(条件对象)
Condition class threading.Condition(lock=None 这个类实现条件变量对象.条件变量允许一个或多个线程等待,知道它们被另一个线程唤醒. 如果给出了lock参数而 ...
- java多线程 -- Condition 控制线程通信
Api文档如此定义: Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对 ...
- [Python 多线程] Condition (十)
Condition常用于生产者.消费者模型,为了解决生产者消费者速度匹配问题. 构造方法Condition(lock=None),可以传入一个Lock或RLock对象,默认RLock. 方法: acq ...
- 关于Python多线程condition变量的应用
''' 所谓条件变量,即这种机制是在满足了特定的条件后,线程才可以访问相关的数据. 它使用Condition类来完成,由于它也可以像锁机制那样用,所以它也有acquire方法和release方法,而且 ...
- Java之多线程开发时多条件Condition接口的使用
转:http://blog.csdn.net/a352193394/article/details/39454157 我们在多线程开发中,可能会出现这种情况.就是一个线程需要另外一个线程满足某某条件才 ...
随机推荐
- appium+python自动化51-adb文件导入和导出(pull push)
前言 用手机连电脑的时候,有时候需要把手机(模拟器)上的文件导出到电脑上,或者把电脑的图片导入手机里做测试用,我们可以用第三方的软件管理工具直接复制粘贴,也可以直接通过adb命令导入和导出. adb ...
- [Android Pro] 使用CursorLoader异步加载数据 from 3.0
Android 3.0引入了CursorLoader实现异步加载数据,为了避免同步查询数据库时阻塞UI线程的问题.在API 11之前可以通过下载支持库,来使之前的系统支持此功能,下载页面为 http: ...
- 谈谈Ext JS的组件——布局的用法续一
盒子布局 盒子布局主要作用是以水平(Ext.layout.container.HBox)或垂直方式(Ext.layout.container.VBox)来划分容器区域.这也是比較常有的布局方式. 使用 ...
- Spring框架学习(2)IOC学习
内容源自:IOC理解 spring ioc注入的三种方式 ioc工厂bean深入理解 耦合性,在java中表现为类之间的关系,耦合性强说明类之间的依赖关系强: 侵入性:框架对代码的侵入: 在传统 ...
- decorator在Python中的作用
decorator(装饰器)在python中作用,可以起到代码复用,也可以起到AOP(面向横切面)的作用. 另外很重要的一点应该就是function在python的世界中是作为一等公民存在的. 在py ...
- [Angular] Extract Implementation Details of ngrx from an Angular Application with the Facade Pattern
Extracting away the implementation details of ngrx from your components using the facade pattern cre ...
- Android6.0指纹识别开发
近期在做android指纹相关的功能,谷歌在android6.0及以上版本号对指纹识别进行了官方支持.当时在FingerprintManager和FingerprintManagerCompat这两个 ...
- 十大迷你iPhone天气应用
来源:GBin1.com 天气特别是指大气情况这样的状态通常包括温度,风,云,湿度和降雨等.上述情况下的天气状况很大程度影响了我们的生活和每天的日常活动.天气可能会经常出乎意料,所以往往希望能够准确提 ...
- zookeeper伪分布式集群安装
1.安装3个zookeeper 1.1创建集群安装的目录 1.2配置一个完整的服务 这里不做详细说明,参考我之前写的 zookeeper单节点安装 进行配置即可,此处直接复制之前单节点到集群目录 创建 ...
- iPhone销售拉动 鸿海精密第一季度利润增长21%
据美国<华尔街日报>5月15日消息,苹果公司主要代工厂鸿海精密发布,第一季度利润增长21%.主要得益于iPhone手机销量强劲以及生产效率提升. 这家全球最大的电子产品代工商近一半的收入是 ...