wait()表示把线程挂起,挂起的时候会自动释放锁。数组
notify() 随机的选择一个在指定对象上挂起的线程激活。缓存
notifyAll() 激活指定对象上挂起的全部线程测试
条件队列:一组等待线程集合,可以经过某种方式来等待对应的条件为真。条件队列中的元素是一个正在等待相关条件的线程。this
经过条件队列构建高可响应的状态依赖类,条件等待存在三元关系 加锁、wait、一个条件谓词(包含多个状态变量) ,状态变量由一个锁保护spa
在测试条件谓语以前必须先得到对象的锁。锁对象和条件队列对象(即调用wait()和notify()方法的对象)必须是同一个对象。线程
以下实现自定义有界缓存实现code
基类代码对象
package com.lifeStudy.algorith; public abstract class BaseBoundedBuffer<V> { private final V[] buf; private int tail; private int head; private int count; protected BaseBoundedBuffer(int capacity) { //还能够经过直接new Object[]数组,等到须要具体化时候才 强制转换单个元素 buf = (V[]) new Object[capacity];//泛型擦除,其实就是(Object[])转换 } protected synchronized final void doPut(V v) { buf[tail] = v; if (++tail == buf.length) { tail = 0; } count++; } protected synchronized final V doTake() { V rs = buf[head]; buf[head] = null; if (++head == buf.length) { head = 0; } count--; return rs; }
//下面是两个状态变量,队列是否满;队列是否为空 经过内置锁对象this public synchronized final boolean isFull() { return count == buf.length; } public synchronized final boolean isEmpty() { return count == 0; } }
经过wait()实现条件队列blog
package com.lifeStudy.algorith; public class BoundedBuffer<V> extends BaseBoundedBuffer<V> {//条件队列 protected BoundedBuffer(int capacity) { super(capacity); } public synchronized void put(V v) throws InterruptedException { while (isFull()) { System.out.println(Thread.currentThread().getId() + " put竞争失败,挂起"); this.wait(); System.out.println(Thread.currentThread().getId() + " put被唤醒,二次激活"); } doPut(v); this.notifyAll();//唤醒全部在this对象上挂起的线程 } public synchronized V take() throws InterruptedException { while (isEmpty()) { System.out.println(Thread.currentThread().getId() + " get竞争失败,挂起"); this.wait();//线程挂起,放开锁synchronized中this对象。 System.out.println(Thread.currentThread().getId() + " get被唤醒,二次激活"); } V v = doTake(); this.notifyAll();//唤醒全部在this对象上挂起的线程 return v; } public static void main(String... args) throws InterruptedException { BoundedBuffer<Integer> integerBoundedBuffer = new BoundedBuffer<Integer>(12); // new Thread(new Consummer(integerBoundedBuffer)).start(); // TimeUnit.SECONDS.sleep(10); new Thread(new Producer(integerBoundedBuffer)).start(); //经过下面能够看到 调用wait挂起线程时会释放锁. // new Thread(new Producer(integerBoundedBuffer)).start(); } private static class Consummer implements Runnable { private final BoundedBuffer bf; public Consummer(BoundedBuffer bf) { this.bf = bf; } public void run() { try { while (true) { bf.take(); System.out.println("get"); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } private static class Producer implements Runnable { private final BoundedBuffer bs; protected Producer(BoundedBuffer bs) { this.bs = bs; } public void run() { try { while (true) { bs.put(123); System.out.println("put"); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } }