005并发容器类-BlockingQueue接口

ConcurrentLinkedQueue(无界队列):

//1.高性能的无阻塞无界队列ConcurrentLinkedQueue
        
        //无界队列不用定义长度
        ConcurrentLinkedQueue<String> clq = new ConcurrentLinkedQueue();
        //添加元素有两种方法offer()和add(),他们没有区别
        clq.offer("a");
        clq.add("b");
        clq.add("c");
        clq.add("d");
        //获取数据,使用poll()获取头部数据,并且将头部数据移除
        System.out.println("头部取出元素:"+clq.poll());//从头部取出一个元素,并且从容器本身移除
        System.out.println("容器长度:"+clq.size());
        
        System.out.println("头部取出元素:"+clq.peek());//从头部取出一个元素,但不会从容器本身移除
        System.out.println("容器长度:"+clq.size());
        

ArrayBlockingQueue(有界队列):基于数组的阻塞队列实现,在ArrayBlockingQueue内部维护了一个有限长度的数组(即定长数组),以便缓存对列中的数据对象,其内部没有实现读写分离,也就意味着生产和消费不能完全并行,其长度是需要定义的,可以指定先进先出(FIFO),其属于有界队列,应用场景很多。

//2.基于阻塞- 有界队列ArrayBlockingQueue,需要定义长度ArrayBlockingQueue<>(5)
        /*其为有界队列,单线程操作,不支持高并发
         * 不能实现生产和消费并行*/
        //ArrayBlockingQueue内部结构是维护这一个有界的数组
        ArrayBlockingQueue<String> abq = new ArrayBlockingQueue<>(5);
        //添加元素
        abq.put("a");
        abq.add("b");
        abq.add("c");
        abq.add("d");
        abq.add("e");
        //使用offer添加元素,如果可以添加返回true,如果不可以返回false,此处应用带有延迟时间和时间戳的offer方法
        System.out.println(abq.offer("f", 2, TimeUnit.SECONDS));
        
        //应用drainTo进行队列拷贝
        ArrayBlockingQueue<String> abq1 = new ArrayBlockingQueue<>(5);
        abq.drainTo(abq1,3);//将abq容器中的元素拷贝3个到abq1中
        //循环队列
        for(Iterator iterator = abq1.iterator();iterator.hasNext();) {
            String string = (String) iterator.next();
            System.out.println("元素:"+string);
        }

LinkedBlockingQueue:基于链表的阻塞队列同ArrayBlockingQueue类似,其内部也维持着一个数据缓冲队列(该队列由一个链表构成),LinkedBlockingQueue之所以能够高效的处理并发数据,是因为其内部实现采用分离锁(读写分离两个锁),从而实现生产者和消费者操作的完全并行运行,他是一个无界队列。

/*3.基于阻塞- 无界队列LinkedBlockingQueue
         * 基于链表的阻塞队列LinkedBlockingQueue,内部维护着链表,
         * 能够高效处理并发数据,其内部实现分离锁(读写分离两个锁),从而
         * 实现生产者和消费者操作完全并行;
         * 使用方法基本等同于ArrayBlockingQueue
          */
        LinkedBlockingQueue<String> lbq = new LinkedBlockingQueue<>();
        lbq.put("a");
        lbq.add("b");
        lbq.add("c");
        lbq.add("d");
        lbq.add("e");
        lbq.add("f");
        lbq.add("g");
        System.out.println(lbq.offer("h", 1, TimeUnit.SECONDS));
        System.out.println("容器大小"+lbq.size());
        System.out.println("poll()从头部取出元素"+lbq.poll());
        System.out.println("poll方法取出元素后容器大小"+lbq.size());
        System.out.println("peek()从头部取出元素"+lbq.peek());
        System.out.println("peek方法取出元素后容器大小"+lbq.size());
        
        LinkedBlockingQueue<String> lbq1 = new LinkedBlockingQueue<>();
        lbq.drainTo(lbq1,3);
        for(Iterator iterator = lbq1.iterator();iterator.hasNext();) {
            String string = (String) iterator.next();
            System.out.println("lbq1元素:"+string);
        }

SynchronousQueue :一种没有缓冲的队列生产者产生的数据直接会被消费者获取并消费  

/*4.没有缓存的队列 SynchronousQueue(不能盛放任何元素的阻塞队列)
         * 生产者生产的数据直接会被消费者获取并消费
         * 它同时也是一种阻塞队列
         * 实现快速的获取与投递机制:正常场景下必须有一个A获取元素线程阻塞在容器中,
         * 然后B投递元素线程投递后激活A线程完成获取;如果B投递线程先投递就会出现异常;
         */
        SynchronousQueue<String> sq = new SynchronousQueue();
        
        //sq.add("a");//直接添加报 Queue full异常
        //定义获取元素的线程并启动,进入等待
        new Thread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                //线程要先获取元素
                try {
                    System.out.println("元素内容"+sq.take());
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        },"t1").start();
        
        //定义添加元素的线程,并激活获取元素的线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                sq.add("a");
            }
        },"t2").start();
        
    }   

关于阻塞队列与非阻塞队列可以参考:https://blog.csdn.net/danengbinggan33/article/details/73105838
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值