用wait/notify 模拟Queue

一、BlockingQueue支持阻塞队列
   此例子主要是模拟LinkBlockingQueue中put和take方法

public class SimulationQueue {
    // 1 装载元素的容器
    private final List<Object> list = Lists.newArrayList();
    // 2 计数器
    private final AtomicInteger count = new AtomicInteger(0);
    // 3 确定容器的上限和下限
    private Integer maxSize;
    private Integer minSize;

    // 4 构造初始值
    public SimulationQueue(int maxSize) {
        this.maxSize = maxSize;
    }

    // 5 初始化一个对象,用于加锁
    private Object lock = new Object();


    /**
     * put(an object) 把an object加到BlockingQueue里面,如果BlockingQueue没有空间
     * 调用此方法的线程被阻断,直到BlockingQueue,有空间添加数据
     *
     * @param obj
     */
    public void put(Object obj) {
        synchronized (lock) {
            while (count.get() == maxSize) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 1 容器中添加元素
            list.add(obj);
            // 2 计数器加1
            count.incrementAndGet();
            System.out.println("新加入的元素为:" + obj);
            // 3 通知其他线程(唤醒)
            lock.notify();
        }
    }

    /**
     * take() 取走排在BlockingQueue里面排在首位的元素,如果BlockingQueue为空
     * 阻断进入等待状态,直到BlockingQueue有新的数据加入
     */
    public Object take() {
        Object ret = null;
        synchronized (lock) {
            while (count.get() == 0) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 1 容器中取出排在首位的元素
            Object firstObj = list.remove(0);
            // 2 计数器递减
            count.decrementAndGet();
            // 3 通知其他线程(唤醒)
            lock.notify();
        }
        return ret;
    }

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

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

        final SimulationQueue m = new SimulationQueue(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();

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值