使用wait/notify模拟生产者和消费者

public class MyQueue {
    //初始化一个容器
    private LinkedList<Object> list = new LinkedList<Object>();

    private AtomicInteger count = new AtomicInteger(0);

    private final int minSize = 0;

    private final int maxSize;

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

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

    private final Object lock = new Object();

    public void put(Object obj) {
        synchronized(lock) {
            while (count.get() == this.maxSize) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            list.add(obj);
            count.incrementAndGet();
            lock.notify(); //通知由于容器空而阻塞的线程
            System.out.println("新加入的元素为:" + obj);
        }
    }

    public Object take() {
        Object ret = null;

        synchronized(lock) {
            while (count.get() == this.minSize) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            ret = list.removeFirst();
            count.decrementAndGet();
            lock.notify(); //通知由于容器满而阻塞的线程
            System.out.println("移除的元素为:" + ret);
        }

        return ret;
    }

    public static void main(String[] args) {
        final MyQueue mq = new MyQueue(5); //必须加final修饰,否则线程中无法使用
        mq.put("a1");
        mq.put("b2");
        mq.put("c3");
        mq.put("d4");
        mq.put("e5");


        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                mq.put(System.currentTimeMillis());
                mq.put(System.currentTimeMillis());
            }
        }, "t1");
        t1.start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                mq.take();
                mq.take();
            }
        }, "t2");
        t2.start();
    }
}
  1. 模拟的是只有一个生产者和一个消费者的情形。如果要模拟多生产者和多消费者的情形,可以使用循环来加多个t1线程作为生产者,多个t2线程作为消费者。
  2. 如果想让该程序无限运行下去,可以将put操作和take操作分别放在一个while(true)的死循环里面。
  3. TimeUnit.SECONDS.sleep()方法比Thread.sleep()更直观。如TimeUnit.SECONDS.sleep(2),很容易知道是2秒,而Thread.sleep(2 * 1000)。从效率上来说,二者几乎没有差别。

    

转载于:https://my.oschina.net/yitiaoxianyu/blog/1236289

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值