Lock中使用Condition实现等待通知
- 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实现等待通知的更多相关文章
- 再谈AbstractQueuedSynchronizer:共享模式与基于Condition的等待/通知机制实现
共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...
- 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现
共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...
- Java 并发编程-再谈 AbstractQueuedSynchronizer 2:共享模式与基于 Condition 的等待 / 通知机制实现
共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...
- Condition实现等待、通知
使用Condition实现等待/通知: import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.L ...
- 十六、Condition等待通知
一.简介 我们可以使用syncronized和wait,notify实现等待通知.而syncronized的高级实现Lock,也可以实现等待通知,需要构造Condition的实例对象. JDK文档:h ...
- Lock接口之Condition接口
之前在写显示锁的是后,在显示锁的接口中,提到了new Condition这个方法,这个方法会返回一个Condition对象 简单介绍一下 Condition接口: 任意一个Java对象,都拥有一组监视 ...
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.c ...
- 显式锁(四)Lock的等待通知机制Condition
任意一个Java对象,都拥有一组监视器方法(定义在根类Object上),主要包括:wait( ).wait(long timeout).notify().notifyAll()方法:这些方法与关 ...
- 使用Condition配合await()和signal()实现等待/通知
关键字Synchronized与wait()和notify()/notifyAll()结合可以实现“等待/通知”模式, Lock类的子类ReentrantLock也可以实现同样的功能,但需要借助Con ...
随机推荐
- Comet OJ - Contest #12
B 整个表格其实是一些联通块,取反操作不能跨连通块.所以直接统计一下每个连通块内数字不对的个数是不是偶数即可 #include<iostream> #include<cstring& ...
- spring 事物(一)—— 事物详解
事务概念回顾 什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行. 事物的特性(ACID): 事务的特性 原子性: 事务是最小的执行单位,不允许分割.事务的原子性确保动作要么全部完成,要么 ...
- Linux常用功能脚本
设置定时任务 crontab -e 1 0 * * * /bin/find /mnt/tomcat/logs/ -mtime +3 -type f -name "*.log" -e ...
- 【串线篇】SQL映射文件delete/ insert/ update标签
一. <insert id="insertEmployee"> INSERT INTO t_employee(empname,gender,email) VALUES( ...
- maven 使用idea运行按钮install
根据需要配置 例: clean install 离线 设置vm 跳过测试 -Xms1024m -Xmx1024m -XX:MaxPermSize=1024m 附(离线+跳过测试): mvn clean ...
- PHP数组函数实现栈与队列的方法介绍(代码示例)
根据php提供的四个关于数组的函数: array_push(),array_pop(),array_unshift(),array_shift() 配合数组本身,一下子就实现了栈(stack)和队例( ...
- linux 应用层常用API/命令
一 API 1. bsearch NAME bsearch - binary search of a sorted array SYNOPSIS #include <stdlib.h> v ...
- leetcode-166周赛-5280-用户分组
题目描述: 自己的提交: class Solution: def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]: ...
- 05-树9 Huffman Codes(30 分)
In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redunda ...
- Integer之常用方法
public static int parseInt(String s, int radix) throws NumberFormatException {} // radix进制 s 换成 10进制 ...