5.5 LockSupport工具
作用:阻塞或者唤醒一个线程。
package java.util.concurrent.locks;
方法名称 | 描述 |
---|---|
void park() | 阻塞当前线程,调用unpark()或者被中断,才能从park()中返回 |
void parkNanos(long nanos) | 阻塞当前线程,最长不超过nanos纳秒 |
void parkUntil(long deadline) | 阻塞当前线程,直到deadline(从1970年开始到deadline时间的毫秒数) |
void unpark(Thread thread) | 唤醒处于阻塞状态的线程thread |
5.6 Condition接口
对比Object的监视器方法和Condition接口
对比项 | Object监视器方法 | Condition |
---|---|---|
前置条件 | 获取对象的锁 | Lock.lock();lock.newCondition()获取Condition对象 |
调用方式 | 直接调用,如object.wait() | 直接调用,如conditon.await() |
等待队列个数 | 一个 | 多个 |
当前线程释放锁并进入等待状态 | 支持 | 支持 |
当前线程释放锁并进入等待状态,在等待状态中不响应中断 | 不支持 | 支持 |
当前线程释放锁并进入超时等待状态 | 支持 | 支持 |
当前线程释放锁并进入等待状态到将来的某个时间 | 不支持 | 支持 |
唤醒等待队列中的一个线程 | 支持 | 支持 |
唤醒等待队列中的所有线程 | 支持 | 支持 |
5.6.1 Condition接口与示例
使用方式,代码示例:
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public void conditionWait()throws InterruptedException{
lock.lock();
try {
condition.await();
} finally {
lock.unlock();
}
}
public void conditionSignal()throws InterruptedException{
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
方法名称 | 描述 |
---|---|
void await() | 当前线程进入等待状态直到被通知signal或中断 |
void awaitUninterruptibly | 当前线程进入等待状态直到被通知,对中断不敏感 |
long awaitNanos(long nanos) | 当前线程进入等待状态直到通知、中断、超时,返回值表示剩余的时间,如果返回值为0或者负值,就表示已经超时了 |
boolean awaitUntil(Date deadline) | 当前线程进入等待状态直到被通知、中断或者到某个时间,如果没有到指定时间就被通知,方法返回true,否则返回false |
void signal() | 唤醒一个等待在Condition上的线程,该线程从等待方法返回前必须获取与Condition相关联的锁 |
void signalAll() | 唤醒所有等待在Condition上的线程,能够从等待方法返回的线程必须获取与Condition相关联的锁 |
示例2:有界队列,当队列为空时,队列的获取操作将会阻塞获取线程,知道队列中有新增元素,当队列已满时,队列的插入操作将会阻塞插入线程,直到队列出现“空位”。
public class BoundedQueue<T> {
private Object[] items;
private int addIndex, removeIndex, count;
private Lock lock = new ReentrantLock();
private Condition notEmpty = lock.newCondition();
private Condition notFull = lock.newCondition();
public BoundedQueue(int size) {
items = new Object[size];
}
//添加一个元素,如果数组满,则添加线程进入等待状态,直到有空位
public void add(T t) throws InterruptedException {
lock.lock();
try {
while (count == items.length) {
notFull.await();
}
items[addIndex] = t;
if (++addIndex == items.length) {
addIndex = 0;
}
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
// 由头部删除一个元素,如果数组为空,则删除线程进入等待状态,直到有新添加元素
public T remove() throws InterruptedException {
lock.lock();
try {
while (count == 0) {
notEmpty.await();
}
Object x = items[removeIndex];
if (++removeIndex == items.length) {
removeIndex = 0;
}
--count;
notFull.signal();
return (T) x;
} finally {
lock.unlock();
}
}}
当数组数量等于数组长度时,说明数组已经满了,则调用notFull.await(),当前线程随之释放锁并进入等待状态。
当数组数量不等于数组长度时,表示数组未满,则添加元素到数组中,同时通知等待在notEmpty上的线程,数组中已经有新元素可以获取。