多线程学习笔记十一——java里的阻塞队列

ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。
·LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。
·PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。
·DelayQueue:一个使用优先级队列实现的无界阻塞队列。
可用于缓存,但redis已经有类似功能,所以感觉没什么用。
·SynchronousQueue:一个不存储元素的阻塞队列。每一个put操作必须等待一个take操作,
否则不能继续添加元素。
·LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。LinkedTransferQueue多了tryTransfer和transfer方法。transfer方法可以把生产者传入的元素立刻transfer(传输)给消费者。如果没有消费者在等
待接收元素,transfer方法会将元素存放在队列的tail节点,并等到该元素被消费者消费了才返
回。
·LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列,双向阻塞队列可以
运用在“工作窃取”模式中。
ArrayBlockingQueue使用示例:

package day5;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ArrayBlockingQueueTest {
    ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
    public static void main(String[] args) {
        ArrayBlockingQueueTest test = new ArrayBlockingQueueTest();
        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.execute(test.new Productor(test.queue));
        executor.execute(test.new Consumer(test.queue));
    }
    class Productor implements Runnable{
        private ArrayBlockingQueue<String> queue;
        public Productor(ArrayBlockingQueue<String> queue) {
            this.queue = queue;
        }
        @Override
        public void run() {
            String[] element = {"shidebin","jiangxi","shanghai"};
            for(String item:element) {
                try {
                    queue.put(item);
                    System.out.println("插入值:"+item);
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        }
    }
    class Consumer implements Runnable{
        private ArrayBlockingQueue<String> queue;
        public Consumer(ArrayBlockingQueue<String> queue) {
            this.queue = queue;
        }
        @Override
        public void run() {
            while(true) {
                try {
                    String value = queue.take();
                    System.out.println("取到值:"+value);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

console输出:

插入值:shidebin
取到值:shidebin
插入值:jiangxi
取到值:jiangxi
插入值:shanghai
取到值:shanghai

高并发下LinkedBlockingQueue比ArrayBlockingQueue一般要高,因为ArrayBlockingQueue在put和take时使用的同一个ReentrantLock,而LinkedBlockingQueue在put和take时使用了不同的锁,但要注意的是LinkedBlockingQueue在创建时需要指定大小,默认情况下是无界的,源码如下:

/**
     * Creates a {@code LinkedBlockingQueue} with a capacity of
     * {@link Integer#MAX_VALUE}.
     */
    public LinkedBlockingQueue() {
        this(Integer.MAX_VALUE);
    }

    /**
     * Creates a {@code LinkedBlockingQueue} with the given (fixed) capacity.
     *
     * @param capacity the capacity of this queue
     * @throws IllegalArgumentException if {@code capacity} is not greater
     *         than zero
     */
    public LinkedBlockingQueue(int capacity) {
        if (capacity <= 0) throw new IllegalArgumentException();
        this.capacity = capacity;
        last = head = new Node<E>(null);
    }

猜你喜欢

转载自blog.csdn.net/shidebin/article/details/82657966