线程学习记录06-wait和notify模拟queue

使用wait和notify可以线程之间的通信(这两个方法是object的类 的方法,所有的对象都可以使用这两个方法)
1.wait和notify必须配合synchronize关键字使用
2.wait方法释放锁,notify方法不释放锁

如下代码,可以利用wait和notify模拟实现queue

public class MyQueue {

/**
 * 容器
 */
private final LinkedList<Object> list = new LinkedList<>();

/**
 * 原子数据
 */
private final AtomicInteger count = new AtomicInteger(0);

private final int maxSize;
private final int minSize = 0;

private final Object lock = new Object();

public MyQueue (int maxSize){
    this.maxSize = maxSize;
}

public void put (Object obj) {
    synchronized(lock){
        while(count.get() == maxSize){
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        list.add(obj);
        count.getAndIncrement();
        System.out.println(" 元素 " + obj + " 被添加 ");
        lock.notify();

    }
}

public Object take(){
    Object temp = null;
    synchronized (lock) {
        while(count.get() == minSize){
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count.getAndDecrement();
        temp = list.removeFirst();
        System.out.println(" 元素 " + temp + " 被消费 ");
        lock.notify();
    }
    return temp;
}

public int size(){
    return count.get();
}


public static void main(String[] args) throws Exception {

    final MyQueue m = new MyQueue(5);
    m.put("a");
    m.put("b");
    m.put("c");
    m.put("d");
    m.put("e");
    System.out.println("当前元素个数:" + m.size());
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            m.put("h");
            m.put("i");
        }
    }, "t1");

    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                Object t1 = m.take();
                //System.out.println("被取走的元素为:" + t1);
                Thread.sleep(1000);
                Object t2 = m.take();
                //System.out.println("被取走的元素为:" + t2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }, "t2");

    t1.start();
    Thread.sleep(1000);
    t2.start();

}}

运行结果:

image.png

当容器被填满之后,如果添加数据线程就会在lock对象上进入阻塞状态,直到当容易的数据减少之后,由t2线程唤醒在lock对象上阻塞的线程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容