Conditon等待/通知机制

来源

condition的API和Object的wait、notify用法大致相同,但是Object需要配合synchronized来使用,如果使用显示锁Lock无法使用。因此Condition应运而生,他是由Lock的API创建出来的等待/通知机制

API

await()、signal()和wait()、notify()相同,但是使用前需要加锁,Lock.lock

与Object区别

Lock.newCondition()可以获取多个Condition,也就是说,在一个lock对象上,可以有多个等待队列,而Object的等待通知在一个Object上,只能有一个等待队列。

Condition模拟阻塞队列

public class BoundedQueue1<T> {
    public List<T> q; //这个列表用来存队列的元素
    private int maxSize; //队列的最大长度
    private Lock lock = new ReentrantLock();
    private Condition addConditoin = lock.newCondition();
    private Condition removeConditoin = lock.newCondition();

    public BoundedQueue1(int size) {
        q = new ArrayList<>(size);
        maxSize = size;
    }

    public void add(T e) {
        lock.lock();
        try {
            while (q.size() == maxSize) {
                addConditoin.await();
            }
            q.add(e);
            removeConditoin.signal(); //执行了添加操作后唤醒因队列空被阻塞的删除操作
        } catch (InterruptedException e1) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }

    public T remove() {
        lock.lock();
        try {
            while (q.size() == 0) {
                removeConditoin.await();
            }
            T e = q.remove(0);
            addConditoin.signal(); //执行删除操作后唤醒因队列满而被阻塞的添加操作
            return e;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return null;
        } finally {
            lock.unlock();
        }
    }

}

Object的wait/notify模拟阻塞队列

public class MyBlockQueue {
	private Object[] objs; // 数据数组
	private volatile int count; // 当前数组中对象个数
	private volatile int putIndex; // 数组中存储对象的索引
	private volatile int takeIndex; // 数组中取对象的索引
	private Object full;
	private Object empty;

	public MyBlockQueue(int size) {
		super();
		count = 0;
		putIndex = 0;
		takeIndex = 0;
		objs = new Object[size];
		full = new Object();
		empty = new Object();
	}

	private void add(Object obj) {
		synchronized (full) {
			while (objs.length == count) {
				try {
					full.wait();
				} catch (InterruptedException e) {
					Thread.currentThread().interrupt();
				}
			}
			System.out.println("list add:" + obj);
			objs[putIndex] = obj; // 根据索引依次存
			if (++putIndex == objs.length) { // 当数组存满,从0开始存,从1开始取
				putIndex = 0;
			}
		}
		synchronized (empty) {
			++count;
			empty.notify();
		}
	}

	private Object get() {
		Object obj;
		synchronized (empty) {
			try {
				while (count == 0) {
					empty.wait();
				}
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
			}
			obj = objs[takeIndex];
			if(takeIndex + 1 == objs.length) {
				takeIndex = 0;
			}else {
				takeIndex++;
			}
		}
		synchronized (full) {
			count--;
			full.notify();
			System.out.println(Thread.currentThread().getName() + ":" + obj);
			return obj;
		}
	}

	public static void main(String[] args) throws InterruptedException {
		MyBlockQueue m = new MyBlockQueue(5);

		for (int i = 0; i < 2; i++) {
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					m.get();
				}
			}).start();
		}
		for (int i = 0; i < 10; i++) {
			new Thread(new Runnable() {

				@Override
				public void run() {
					Object obj = new Object();
					m.add(obj);
				}
			}).start();
		}


	}
}

猜你喜欢

转载自blog.csdn.net/qq_36382225/article/details/83990762