读书笔记《JAVA并发编程的艺术》 第五章 Java中的锁 5.5 LockSupport工具 5.6 Condition接口

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上的线程,数组中已经有新元素可以获取。

猜你喜欢

转载自blog.csdn.net/maohoo/article/details/81475361