首页  

基于 ReentrantLock Condition await signalAll 实现简单的阻塞队列     所属分类 java 浏览量 832
Condition 下的方法
await        释放锁,并进入等待队列
signal       唤醒等待队列里的任一线程(唤醒哪一个不确定)
signalAll    唤醒等待队列里的所有线程


配合 ReentrantLock 使用

否则抛异常 java.lang.IllegalMonitorStateException


ReentrantLock Condition
等待队列 同步队列
signal / signalAll 把等待队列中的线程放到同步队列

ReentrantLock 支持 公平和非公平锁 ,默认 非公平锁


例子代码 ,不考虑效率 ,注意与 juc LinkedBlockingQueue 的区别

LinkedBlockingQueue 使用了2个读写锁  2个Condition ,并且 使用 signal 唤醒一个线程
例子只使用一个锁和Condition

// Lock held by take, poll, etc 
private final ReentrantLock takeLock = new ReentrantLock();

// Wait queue for waiting takes 
private final Condition notEmpty = takeLock.newCondition();

// Lock held by put, offer, etc 
private final ReentrantLock putLock = new ReentrantLock();

// Wait queue for waiting puts 
private final Condition notFull = putLock.newCondition();
    
    



public class SimpleBlockQueue2 {

	private final int maxSize;
	private final LinkedList<Object> list = new LinkedList<>();
	private static final Lock lock = new ReentrantLock();
	private static final Condition condition = lock.newCondition();

	public SimpleBlockQueue2(int maxSize) {
		if (maxSize <= 0 || maxSize >= 100) {
			throw new RuntimeException("maxSize error");
		}
		this.maxSize = maxSize;
	}

	public void offer(Object e) throws InterruptedException {
		lock.lock();
		try {
			while (list.size() >= maxSize) {
				condition.await();
			}
			list.add(e);
			condition.signalAll();
		} finally {
			lock.unlock();
		}
	}

	public Object poll() throws InterruptedException {
		lock.lock();
		try {
			while (list.isEmpty()) {
				condition.await();
				// condition.await(900,TimeUnit.MILLISECONDS);
			}
			Object e = list.poll();
			condition.signalAll();
			return e;
		} finally {
			lock.unlock();
		}
	}
	


完整代码
https://gitee.com/dyyx/hellocode/blob/master/src/SimpleBlockQueue2.java


ReentrantLock原理 基于 wait 和 notifyAll 实现简单的阻塞队列 Lock和synchronized的区别 synchronized知识点

上一篇     下一篇
LockSupport简介

ReentrantLock原理

基于 wait 和 notifyAll 实现简单的阻塞队列

Synchronized 和 AQS 实现要点

java死锁实例

SpringBoot启动过程简介