使用显示条件变量Lock.Condition实现的有界缓存

1、wait,notify,notifyAll

 同一个对象Object o,线程A调用wait方法在o的阻塞队列上进行等待a条件满足的notify通知,线程B调用wait方法在o的阻塞队列上进行等待b条件满足的notify通知。
 对象o上的阻塞队列中等待的任务不是同一种类型,导致为了避免通知信号丢失,而使用notifyAll进行通知,也就是说A或者B中的某一个满足条件时,要使用notifyAll来通知等待在o上的所有阻塞线程。
 因为假设当线程A线程满足等待条件时,使用notify进行通知时,通知的阻塞线程可能是A,也可能是B,如果通知到B的话,那就发生了信号丢失,实际想要通知的线程并没有获得通知。只有使用notifyAll才能保证通知到o上所有的阻塞线程。

2、Lock,Condition

 一个Condition和一个Lock关联在一起,就像一个对象上的一个等待通知线程与阻塞队列一样。每个Lock,可以创建任意数量的Condition对象。调用lock上的Lock.newCondition方法即可。

特别注意:在Condition对象中,与wait、notify和notifyAll方法对应的分别是await、signal和signalAll。但是,Condition对Object进行了扩展,因而它也包含wait和notify方法。一定要确保使用正确的版本—await和signal。

3、使用显示条件变量的有界缓存

@ThreadSafe
public class ConditionBoundedBuffer <T> {
    protected final Lock lock = new ReentrantLock();
    // CONDITION PREDICATE: notFull (count < items.length)
    private final Condition notFull = lock.newCondition();
    // CONDITION PREDICATE: notEmpty (count > 0)
    private final Condition notEmpty = lock.newCondition();
    private static final int BUFFER_SIZE = 100;
    @GuardedBy("lock") private final T[] items = (T[]) new Object[BUFFER_SIZE];
    @GuardedBy("lock") private int tail, head, count;

    // BLOCKS-UNTIL: notFull
    public void put(T x) throws InterruptedException {
        lock.lock();
        try {
            while (count == items.length)
                notFull.await();
            items[tail] = x;
            if (++tail == items.length)
                tail = 0;
            ++count;
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    // BLOCKS-UNTIL: notEmpty
    public T take() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0)
                notEmpty.await();
            T x = items[head];
            items[head] = null;
            if (++head == items.length)
                head = 0;
            --count;
            notFull.signal();
            return x;
        } finally {
            lock.unlock();
        }
    }
}

你可能感兴趣的:(并发编程,编程,Java,Java并发实战-学习笔记)