• Java并发编程-阻塞队列


    Java concurrent 包中BlockingQueue接口有ArrayBlockingqueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousBlockingQueue等几个实现类。

    1、ArrayBlockingqueue

    通过名字可以看出,ArrayBlockingqueue是通过数组实现的定长队列,遵循FIFO(先进先出)原则,队列头部元素位于队列中的时间最长,队列尾部的元素位于队列中的时间最短。新到的元素放入队列尾部,取元素时从头部取。

    队列一旦初始化后,大小就确定了。队列满了后再向其中添加元素就会阻塞队列。同理,向空的队列取元素也会发生阻塞。

    2、LinkedBlockingQueue

    该队列自然是通过链表实现的,与ArrayBlockingQueue不同的是,该队列是基于链表节点实现,节点动态生成,队列默认最大长度是整数型变量最大值,即231-1,可以通过构造方法自己指定队列的长度。由于LinkedBlockingQueue生产和消费数据分别采用独立的锁,所以在高并发情况下,其吞吐量要高于ArrayBlockingQueue,但在大多数应用中,其可预知的性能要低。

    3、PriorityBlockingQueue

    该队列中的元素是按顺序结构存储中,添加到队列中的元素必须实现Comparable接口的compareTo()方法。在向队列中添加元素时,会与原队列中的元素进行比较,直到找到它的位置。该队列不允许null值。

    4、SynchronousBlockingQueue

    对于SynchronousBlockingQueue来说,入队和出队操作是交替进行的,也就是说一个线程进行insert操作后,必须等待另一个线程进行remove操作才能再次进行insert操作,反之亦然。

     下面是一个用LinkedBlockingQueue关于生产者和消费者一个例子:

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.LinkedBlockingQueue;
    
    
    public class BlockingQueue {
        private static LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<Integer>();
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            executorService.submit(new Producer("producer 1"));
            executorService.submit(new Producer("producer 2"));
            executorService.submit(new Producer("producer 3"));
    
            executorService.submit(new Consumer("consumer 1"));
            executorService.submit(new Consumer("consumer 2"));
            executorService.submit(new Consumer("consumer 3"));
    
    
    
        }
    
        static class Producer implements Runnable{
            private String name;
            public Producer(String name){
                this.name = name;
            }
    
            @Override
            public void run() {
                for(Integer i=0;i<10;i++){
                    System.out.println(this.name + " produce " + i);
                    linkedBlockingQueue.add(i);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
    
        static class Consumer implements Runnable{
            private String name;
            public Consumer(String name){
                this.name=name;
            }
            @Override
            public void run() {
                for(Integer i=0;i<10;i++){
                    try {
                        System.out.println(this.name + " consume " + linkedBlockingQueue.take());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
    
    }
    
    
  • 相关阅读:
    埋点笔记整理02
    数据可视化笔记整理02
    埋点笔记整理01
    数据可视化笔记整理01
    魔力Python——我踩过的各种坑
    我们的竞争对手在看向哪里---对勺海公众号的挖掘与细分
    JDBC核心技术(获取数据库链接、数据库事务、数据库链接池)
    Vue封装axios
    JAVA_基础反射机制
    dispaly的Grid布局与Flex布局
  • 原文地址:https://www.cnblogs.com/lishenghua/p/7366423.html
Copyright © 2020-2023  润新知