并发编程系列之掌握Condition接口使用
【摘要】
并发编程系列之掌握Condition接口使用
1、什么是Condition接口
Condition是jdk的juc包中提供的并发等待api,俗称条件等待,条件变量,用于在Lock中提供synchron...
并发编程系列之掌握Condition接口使用
1、什么是Condition接口
Condition是jdk的juc包中提供的并发等待api,俗称条件等待,条件变量,用于在Lock中提供synchronized加Object的wait/notify
等待通知模式。
注意,Condition只是一个api接口,具体实现还是依赖于具体的lock类,比如使用
new ReentrantLock().newCondition();
- Object中的
wait()
,notify()
,notifyAll()
和synchronized配合使用,可以唤醒一个或者全部 - Condition需要和lock实现类配合使用,一个Lock实例可以创建多个Condition,一个条件一个等待集合,可根据条件精确控制等待线程
多线程读取队列,写入数据后,唤醒读取线程继续执行。读取数据后,唤醒写线程继续执行
2、Condition接口常用方法
用idea编辑器查看Condition方法,如图:
await()
:当前线程在接到信号或被中断之前一直处于等待状态await(long time, TimeUnit unit)
:当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。awaitNanos(long nanosTimeout)
:当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。返回值表示剩余时间,如果在nanosTimesout之前唤醒,那么返回值 = nanosTimeout - 消耗时间,如果返回值 <= 0 ,则可以认定它已经超时了。awaitUninterruptibly()
:当前线程在接到信号之前一直处于等待状态。该方法对中断不敏感awaitUntil(Date deadline)
:当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。如果没有到指定时间就被通知,则返回true,否则表示到了指定时间,返回返回false。signal()
:唤醒一个等待线程。该线程从等待方法返回前必须获得与Condition相关的锁。signal()All
:唤醒所有等待线程。能够从等待方法返回的线程必须获得与Condition相关的锁。
2、Condition例子
利用Condition实现生产者消费者模式:
import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionLockQueue {
private LinkedList<Object> queue;
private volatile int capacity;
private Condition productCondition = null;
private Condition consumeCondition = null;
private Lock lock;
public ConditionLockQueue(int capacity) {
this.queue = new LinkedList<Object>();
this.capacity = capacity;
lock = new ReentrantLock();
this.productCondition = lock.newCondition();
this.consumeCondition = lock.newCondition();
}
public void put(Object obj) throws InterruptedException {
lock.lock();
try {
while (queue.size() == capacity) {
productCondition.await();
System.out.println("产品仓库满了,不能生产!");
}
queue.add(obj);
System.out.println("[Producer]: " + obj+ ",共有:"+queue.size());
consumeCondition.signal();
} finally {
lock.unlock();
}
}
public Object sub() throws InterruptedException {
Object obj = null;
lock.lock();
try {
while (queue.size() == 0) {
consumeCondition.await();
System.out.println("没有产品了,需要生产!");
}
Object prod = queue.remove(0);
System.out.println("[Consumer]: " + prod + ",共有:"+queue.size());
productCondition.signal();
}finally {
lock.unlock();
}
return obj;
}
public boolean isEmpty() {
return (queue.size() == 0);
}
public static void main(String[] args) throws InterruptedException {
Random random = new Random();
ConditionLockQueue queue = new ConditionLockQueue(10);
Runnable produceTask = () -> {
for (; ;) {
try {
queue.put(random.nextInt(10));
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable consumeTask = () -> {
for (; ;) {
try {
queue.sub();
Thread.sleep(random.nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//3个生产者
new Thread(produceTask).start();
new Thread(produceTask).start();
new Thread(produceTask).start();
//3个消费者
new Thread(consumeTask).start();
new Thread(consumeTask).start();
new Thread(consumeTask).start();
}
}
- 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
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
附录参考资料
- https://www.cnblogs.com/gemine/p/9039012.html
- https://www.tutorialspoint.com/java_concurrency/concurrency_condition.html
文章来源: smilenicky.blog.csdn.net,作者:smileNicky,版权归原作者所有,如需转载,请联系作者。
原文链接:smilenicky.blog.csdn.net/article/details/121672160
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)