Java multi-threading - Detailed blocking queue

definition

  • Queue: wherein elements FIFO

  • When the queue is empty it will be blocked when the queue is full will block when the write queue space, access to queue data: obstruction.

  • Fact: the queue is empty when retrieving an element of thread waits for the queue to become non-empty. When the queue is full, the thread will wait queue storage elements available.

Inheritance blocking queue

  • ArrayBlockingQueue: a structure consisting of an array bounded blocking queue.

  • LinkedBlockingQueue: a linked list of structures bounded blocking queue.

  • PriorityBlockingQueue: a support prioritization of unbounded blocking queue.

  • DelayQueue: Use a priority queue unbounded blocking queue implementation.

  • SynchronousQueue: a blocking queue element is not stored.

  • LinkedTransferQueue: a list structure consisting of unbounded blocking queue.

  • LinkedBlockingDeque: a linked list structure consisting of two-way blocking queue.

Common method

Detailed

  • add (e) / remove (o ): When blocking throw exception, add / remove a specific element in the queue, the Add operation when the queue space is full, will IllegalStateException is thrown, when the queue space is limited, recommended offer method ; remove (): removes the head of the queue element, when no element is thrown exception NoSuchElementException (queue Interface method)

  • offer (e) / poll (): returns the value when jamming is added to the queue / extraction element, when operating the offer queue space is full, return false; poll operation, the head of the queue element removed, no element returns null

  • put (e) / take: blocked waiting time is added to the queue / delete an element, PUT operation queue is full, by blocking wait; Take operation queue is empty, waiting for blocking the same manner.

Use Demo

Analog blocking queue used in multiple threads, the main thread of the additive element, the other from a queue thread consumption, while the other thread length print queue (queue detecting an occlusion)

public class BlockingQueueDemo {
    // 在主线程向阻塞队列中添加任务,同时开启一个线程消费队列和另一个线程打印队列的长度
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue blockingQueue = new ArrayBlockingQueue<>(4);
        blockingQueue.put(new BlockingQueueRunnable("run-1"));
        blockingQueue.put(new BlockingQueueRunnable("run-2"));
        blockingQueue.put(new BlockingQueueRunnable("run-3"));
        blockingQueue.put(new BlockingQueueRunnable("run-4"));
        ResumeBlockingQueueThread blockingQueueThread = new ResumeBlockingQueueThread(blockingQueue);
        blockingQueueThread.start();
        GetBlockingQueueSize getBlockingQueueSize = new GetBlockingQueueSize(blockingQueue);
        getBlockingQueueSize.start();

        blockingQueue.put(new BlockingQueueRunnable("run-5"));
        blockingQueue.put(new BlockingQueueRunnable("run-6"));
        blockingQueue.put(new BlockingQueueRunnable("run-7"));
        blockingQueue.put(new BlockingQueueRunnable("run-8"));
        blockingQueue.put(new BlockingQueueRunnable("run-9"));
        blockingQueue.put(new BlockingQueueRunnable("run-10"));
    }

    // 阻塞队列中的线程
    private static class BlockingQueueRunnable implements Runnable {
        public BlockingQueueRunnable(String name) {
            this.name = name;
        }
        private String name;

        @Override
        public void run() {
            System.out.println("thread" + name + ": run");
        }
    }

    // 每隔1s消费阻塞队列的元素个数 10次
    private static class ResumeBlockingQueueThread extends Thread {
        BlockingQueue blockingQueue;

        public ResumeBlockingQueueThread(BlockingQueue blockingQueue) {
            this.blockingQueue = blockingQueue;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    //sleep 1s
                    Thread.sleep(2000);
                    blockingQueue.take().run();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 每隔2s打印阻塞队列的元素个数 10次
    private static class GetBlockingQueueSize extends Thread {
        BlockingQueue blockingQueue;

        public GetBlockingQueueSize(BlockingQueue blockingQueue) {
            this.blockingQueue = blockingQueue;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("阻塞队列的长度为:"+blockingQueue.size());
            }
        }
    }
}
复制代码

Use principle

To ArrayBlockingQueue example,

When the need to block, by using the Condition class, were blocked by a thread await method Condition class. Condition class can refer to: the Java multithreading - AQS Detailed

No obstruction, achieved through an array of cycling team included / dequeue

Ref:

  1. JDK8 source

  2. InfoQ talk concurrent (seven) - blocking queue in Java

  3. A realization of their own blocking queue

Reproduced in: https: //juejin.im/post/5d09df3ee51d45775e33f56e

Guess you like

Origin blog.csdn.net/weixin_34295316/article/details/93181314