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();
                }
            }

        }
    }

}

posted on 2017-08-15 17:45  程序生涯点滴记录  阅读(220)  评论(0编辑  收藏  举报