Java并发-19.Condition接口

2019-05-27  本文已影响0人  悠扬前奏

1.Condition接口示例

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 使用Condition的示例
 *
 * @author pengjunzhe
 */
public class ConditionUseCase {
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    public void conditionWait() throws InterruptedException {
        lock.lock();
        try {
            condition.await();
        } finally {
            lock.unlock();
        }
    }

    public void conditionSingnal() throws InterruptedException {
        lock.lock();
        try {
            condition.signal();
        } finally {
            lock.unlock();
        }
    }
}

一般而言,都会将Condition变量作为成员变量。当调用await方法后,当前线程会释放锁并进入Condition变量的等待队列,而其他线程调用signal方法后,通知正在Condition变量等待队列的线程从await方法返回,并且在返回前已经获得了锁。

Condition方法的描述:

方法 描述
void await() throws InterruptedException 当前线程进入等待状态,直到被通知(signal)或者被中断时,当前线程进入运行状态,从await()返回;
void awaitUninterruptibly() 当前线程进入等待状态,直到被通知,对中断不做响应;
long awaitNanos(long nanosTimeout) throws InterruptedException 在接口1的返回条件基础上增加了超时响应,返回值表示当前剩余的时间,如果在nanosTimeout之前被唤醒,返回值 = nanosTimeout - 实际消耗的时间,返回值 <= 0表示超时;
boolean await(long time, TimeUnit unit) throws InterruptedException 同样是在接口1的返回条件基础上增加了超时响应,与接口3不同的是:
可以自定义超时时间单位;
返回值返回true/false,在time之前被唤醒,返回true,超时返回false。
boolean awaitUntil(Date deadline) throws InterruptedException 当前线程进入等待状态直到将来的指定时间被通知,如果没有到指定时间被通知返回true,否则,到达指定时间,返回false;
void signal() 唤醒一个等待在Condition上的线程;
void signalAll() 唤醒等待在Condition上所有的线程。

一个有界队列的例子,当队列为空,队列的获取操作阻塞获取线程,直到队列中有新增元素,队列满时,队列的插入操作会阻塞线程,直到队列出现空位:

package com.junzerg.threads;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author pengjunzhe
 */
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();
        }
    }

    /**
     * 删除一个元素,如果数组为空,则删除线程进入等待状态,直到有心元素添加进来
     */
    @SuppressWarnings("unchecked")
    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();
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读