zoukankan      html  css  js  c++  java
  • JUC 并发编程--06, 阻塞队列(7种), 阻塞等待 api的 代码验证


    这些队列的 api ,就是添加队列,出队列,检测对首元素, 由于 add()--remove(), offer()--poll(),太简单这里不做验证, 只验证后二组api: 阻塞等待( put()--take() ), 超时等待( offer()--poll() )
    多线程下,验证:

    public static void main(String[] args) throws InterruptedException {
        ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue(3);
        /**
         *  阻塞 等待 的 api: 添加队列put(), 出队列take()
         *
         *  take(),从队列中取元素, 如果队列中没有元素,就在这里阻塞,直到队列中有元素,他取走为止,   不拿到元素死不罢休
         *  put(), 放元素到队列中, 如果队列已经满了,就在这里阻塞,直到队列的元素被取走,取走一个放入一个,   一定要放元素到队列中,哪怕等到天荒地老
         */
        //验证 take(), 不拿到元素死不罢休
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName() + "这里获取不到任何东西,所以在这里阻塞等待....");
                String take = arrayBlockingQueue.take();
                System.out.println(Thread.currentThread().getName() + "获取到的值为:" + take);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"线程1").start();
    
        // 这里睡1秒,目的是让 线程1 先执行
        TimeUnit.SECONDS.sleep(1);
    
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName() + "抢到执行权, 此线程放数据开始");
                arrayBlockingQueue.put("1");
                arrayBlockingQueue.put("2");
                arrayBlockingQueue.put("3");
                System.out.println(Thread.currentThread().getName() + "放入成功");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"线程2").start();
        while(Thread.activeCount()>2){}
        System.out.println("打印2:"+arrayBlockingQueue);
     }
    

    运行结果:

    ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue(3);
        /**
         *  阻塞 等待 的 api: 添加队列put(), 出队列take()
         *
         *  take(),从队列中取元素, 如果队列中没有元素,就在这里阻塞,直到队列中有元素,他取走为止,   不拿到元素死不罢休
         *  put(), 放元素到队列中, 如果队列已经满了,就在这里阻塞,直到队列的元素被取走,取走一个放入一个,   一定要放元素到队列中,哪怕等到天荒地老
         */
        //验证 put(), 一定要放元素到队列,哪怕等到天荒地老
        arrayBlockingQueue.put("123");
        arrayBlockingQueue.put("456");
        arrayBlockingQueue.put("789");
        System.out.println("打印1:"+arrayBlockingQueue);
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName() + "想放元素000 到队列中,但此时队列满了,所以开始等待");
                arrayBlockingQueue.put("000");
                System.out.println(Thread.currentThread().getName() + "等待结束了, 终于将000放入队列中了, 结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"线程1").start();
    
        // 这里睡1秒,目的是让 线程1 先执行
        TimeUnit.SECONDS.sleep(1);
    
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName() + "抢到执行权. 开始移除一个元素");
                String take = arrayBlockingQueue.take();
                System.out.println(Thread.currentThread().getName() + "将 "+take+" 移除队列, 方便 线程1 放元素");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"线程2").start();
    
        while(Thread.activeCount()>2){}
        System.out.println("打印2:"+arrayBlockingQueue);
    

    运行结果:

    超时等待 的 api 代码验证

        ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue(3);
        /**
         *  超时等待:带等待时间参数的: 添加队列 offer(,,)  移除队列 poll(,,)
         *
         *  offer(,,) : 队列满了, 就在这里等待, 如果一定时间内.还没有元素被取出, 超过这个世界就退出等待
         *  poll(,,) : 队列为空, 就在这里等待, 如果一定时间内,还没有元素添加到队列中, 超过这个时间就退出等待
         */
        //验证offer(,,)
        arrayBlockingQueue.put("123");
        arrayBlockingQueue.put("456");
        arrayBlockingQueue.put("789");
        System.out.println("初始队列:"+arrayBlockingQueue);
    
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName() + "想要往队列中放元素 0000, 但此时队列已满,等待3秒,3秒之内如果没有元素移除 , 就退出等待,不添加");
                arrayBlockingQueue.offer("0000",3,TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"线程1").start();
    
        new Thread(()->{
            try {
                //TimeUnit.SECONDS.sleep(5);
                System.out.println(Thread.currentThread().getName() + "抢到执行权,开始移除一个元素");
                arrayBlockingQueue.poll();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"线程2").start();
    
        while(Thread.activeCount()>2){}
        System.out.println("打印2:"+arrayBlockingQueue);
    }
    

    运行结果为: 可以看到,队列满, 线程1等了3秒, 3秒内刚好线程2 移除了一个元素, 所以线程1,退出等待,添加0000到队列中

    如果: 线程2 睡5秒呢? 此时可以看到, 线程1 等了3秒,队列依旧是满的, 就退出等待,不执行添加操作, 运行结果为:

    验证 超时等待 poll(,,)

        ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue(3);
        /**
         *  超时等待:带等待时间参数的: 添加队列 offer(,,)  移除队列 poll(,,)
         *
         *  offer(,,) : 队列满了, 就在这里等待, 如果一定时间内.还没有元素被取出, 超过这个世界就退出等待
         *  poll(,,) : 队列为空, 就在这里等待, 如果一定时间内,还没有元素添加到队列中, 超过这个时间就退出等待
         */
        //验证 poll(,,)
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName() + "此时队列为空, 等待3秒,如果3秒内,队列仍然为空,就退出等待,不为空就执行出队列操作");
                String poll = arrayBlockingQueue.poll(3, TimeUnit.SECONDS);
                System.out.println(Thread.currentThread().getName() + "取出的元素是:" + poll);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"线程1").start();
    
        new Thread(()->{
            try {
                //TimeUnit.SECONDS.sleep(5);
                System.out.println(Thread.currentThread().getName() + "开始往队列中放元素");
                arrayBlockingQueue.offer("123");
                arrayBlockingQueue.offer("456");
                System.out.println(Thread.currentThread().getName() + "入队结束");
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"线程2").start();
        while(Thread.activeCount()>2){}
        System.out.println("打印2:"+arrayBlockingQueue);
    

    运行结果: 队列空,线程1,等待3秒, 刚好3秒内,线程2,往队列中添加了元素, 所以 线程1 取到了元素


    如果线程2 等待5秒: 线程1将取不到元素 为null, 结果为:

  • 相关阅读:
    微服务网关常用限流算法
    微服务网关zuul介绍
    Nginx实现微服务网关的简单介绍
    11.9-编写操作者
    11.5-编写程序
    11.3-学习操作者文档
    11.2-LV面向对象编程视频学习及周五与老师交流总结
    10.29-基于LabVIEW的分布式集群机器人控制系统
    10.27-运用操作者框架架设控制中心软件架构
    5.24-29离线解析问题
  • 原文地址:https://www.cnblogs.com/lvcai/p/13572042.html
Copyright © 2011-2022 走看看