前言
package java.util.concurrent.locks
子类
public interface Condition {
void await() throws InterruptedException;
void awaitUninterruptibly();
long awaitNanos(long nanosTimeout) throws InterruptedException;
boolean await(long time, TimeUnit unit) throws InterruptedException;
boolean awaitUntil(Date deadline) throws InterruptedException;
void signal();
void signalAll();
}
实例化
ReentrantLock中
public Condition newCondition() {
return sync.newCondition();
}
final ConditionObject newCondition() {
return new ConditionObject();
}
Condition 配合 Lock 实现 等待和通知机制,非常类似于 wait 和 notify 方法
static ReentrantLock lock = new ReentrantLock();
static Condition condition = lock.newCondition();
condition.await();
condition.signal();
condition.signalAll();
await 类似于 wait, signal 类似于 notify,signalAll 类似于 notifyAll 。
condition.await() 会响应中断,标志位的变化为 false -> true -> false
调用线程的静态方法清除 标志位
超时之后自动返回 false ,超时之前被唤醒返回 true
跟 Object 中 wait 和 notify 对比
condition能够支持多个等待队列(new 多个Condition对象),而Object方式只能支持一个。
condition 可以 awaitUninterruptibly 方法 来实现 不中断等待,也就是不响应 intertupt ,只能通过 signal 来唤醒。
condition 可以 awaitUntil 来等待到将来的某个时间 ,会响应 中断 。
一个 多 Condition的例子
public class D8<E> {
public D8(int size) {
this.size = size;
}
int size;
ReentrantLock lock = new ReentrantLock();
LinkedList<E> list = new LinkedList<>();
Condition add = lock.newCondition();
Condition remove = lock.newCondition();
public void enqueue(E e) throws InterruptedException {
lock.lock();
try {
//满了等待
while (list.size() == size) {
add.await();
}
list.add(e);
System.out.println("入队:" + e);
remove.signal();
} finally {
lock.unlock();
}
}
public E dequeue() throws InterruptedException {
E e;
lock.lock();
try {
//空的等待
while (list.size() == 0) {
remove.await();
}
e = list.removeFirst();
System.out.println("出队:" + e);
add.signal();
return e;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
//
D8<Integer> queue = new D8<>(2);
//
for (int i = 0; i < 10; i++) {
int data = i;
new Thread(() -> {
try {
queue.enqueue(data);
} catch (InterruptedException e) {
}
}
).start();
}
//
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
queue.dequeue();
} catch (InterruptedException e) {
}
}
).start();
}
}
}
-------
入队:1
入队:3
出队:1
入队:7
出队:3
出队:7
入队:9
出队:9
入队:2
出队:2
入队:0
入队:4
出队:0
出队:4
入队:5
出队:5
入队:6
入队:8
出队:6
出队:8
进程已结束,退出代码为 0
链表的大小为2,有两个队列,一个是add,一个是remove,一个生产线程过来生产,如果集合满了,从生产队列上等待,如果集合没满则生产元素并唤醒消费队列的一个线程。一个消费过来消费,如果集合是空的,从消费队列上等待,如果集合不是空的,消费并唤醒生产队列的一个线程。
condition的多队列的优势,一个生产者和两个消费者,如果集合满了,会稳定唤醒消费者参与竞争,而集合为空又会稳定唤醒生产者进行竞争,而一个队列的话,会发生集合满了生产线程去等待了,notify又随机唤醒了生产线程起来做判断,发现满了之后继续等待的过程。