多线程-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 我们在多线程开发中,可能会出现这种情况.就是一个线程需要另外一个线程满足某某条件才 ...
随机推荐
- GUN C/C++ __attribute__ 用法 转
http://blog.csdn.net/mydo/article/details/3738336 GNUC的一大特色(却不被初学者所知)就是__attribute__机制.__attrib ...
- arcgis10.2转shp文件中文乱码问题解决方案
从ArcGIS的数据源入手,自己升级ArcGIS for Desktop到10.2.0,然后用该版本ArcGIS软件重新导出数据,竟然还是乱码.经咨询ArcGIS技术支持,技术支持说必须保证shp文件 ...
- 定时任务框架-quartz 时间配置
quartz定时任务时间设置: 这些星号由左到右按顺序代表 : * * * * * * * 格式: [秒] [分] [小时] [日] [月] [周] [年] * 表示所有值. 例如:在分的字段上设置 ...
- Netty游戏服务器之四protobuf编解码和黏包处理
我们还没讲客户端怎么向服务器发送消息,服务器怎么接受消息. 在讲这个之前我们先要了解一点就是tcp底层存在粘包和拆包的机制,所以我们在进行消息传递的时候要考虑这个问题. 看了netty权威这里处理的办 ...
- CDHtmlDialog 基本使用
跳转 Navigate("res://tt.exe/#138"); 138是html的资源号 输入框的Get,set HRESULT CTTDlg::OnButtonCancel( ...
- OSC的原理
OSC是Online Schema Change简写,即在线架构改变.其实现步骤: 1. init,即初始化阶段,会对创建的表做一些验证工作,如检查表是否有主键,是否存在触发器或者外键等.2. cre ...
- 对象的当前状态使该操作无效 说明: 执行当前 Web 请求期间,出现未处理的异常。
这个异常在页面数据量小的时候并不会触发,只在页面数据量大的情况下才会出现, 异常信息如下: 对象的当前状态使该操作无效. 说明: 执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以 ...
- RawCap抓取本地回环接口数据包
RawCap.exe --help ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 D: ...
- XSS之浪潮已经来临
前些天和Roy厉在微博上聊到微信公众账号,我说我在辛苦运营“网站安全中心”这个账号呢,他说我这账号粉丝少是少了点,不过用户定位精确,我说我不希望精确,因为我在尽可能写科普,科普需要传播. Roy厉说过 ...
- zabbix3.2 报错 Database error
一.Database errorThe frontend does not match Zabbix database. Current database version (mandatory/opt ...