Java阻塞队列的实现

阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。

阻塞队列提供了四种处理方法:

方法\处理方式 抛出异常 返回特殊值 一直阻塞 超时退出
插入方法 add(e) offer(e) put(e) offer(e,time,unit)
移除方法 remove() poll() take() poll(time,unit)
检查方法 element() peek() 不可用 不可用
抛出异常:是指当阻塞队列满时候,再往队列里插入元素,会抛出IllegalStateException(“Queue full”)异常。当队列为空时,从队列里获取元素时会抛出NoSuchElementException异常 。
返回特殊值:插入方法会返回是否成功,成功则返回true。移除方法,则是从队列里拿出一个元素,如果没有则返回null
一直阻塞:当阻塞队列满时,如果生产者线程往队列里put元素,队列会一直阻塞生产者线程,直到拿到数据,或者响应中断退出。当队列空时,消费者线程试图从队列里take元素,队列也会阻塞消费者线程,直到队列可用。
超时退出:当阻塞队列满时,队列会阻塞生产者线程一段时间,如果超过一定的时间,生产者线程就会退出。

  1. Java里的阻塞队列

JDK7提供了7个阻塞队列。分别是

ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。
LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。
PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
DelayQueue:一个使用优先级队列实现的无界阻塞队列。
SynchronousQueue:一个不存储元素的阻塞队列。
LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

简单理解:

阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列,下图展示了如何通过阻塞队列来合作:

线程1往阻塞队列中添加元素,而线程2从阻塞队列中移除元素
从5.0开始,JDK在java.util.concurrent包里提供了阻塞队列的官方实现。尽管JDK中已经包含了阻塞队列的官方实现,但是熟悉其背后的原理还是很有帮助的。

package thread.BlockingQueue;

import sun.awt.CustomCursor;

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

public class BlockingQueueTest {
    /**
     * 生产者
     */
    public static class  Producer implements Runnable{
        private final BlockingQueue blockingQueue;
        //同步变量 volatile
        private volatile boolean flag;
        private Random random;

        public Producer(BlockingQueue blockingQueue){
            this.blockingQueue = blockingQueue;
            flag=false;
            random=new Random();
        }


        @Override
        public void run() {
            while (!flag){
                int info = random.nextInt();
                try {
                    blockingQueue.put(info);
                    System.out.println(Thread.currentThread().getName()+"---->Producer"+info);
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }

        public void shutDown(){
            flag =  true;
        }
    }

    public static class Consumer implements Runnable{

        private final BlockingQueue blockingQueue;
        private volatile boolean flag;
        public Consumer(BlockingQueue blockingQueue){
                this.blockingQueue = blockingQueue;
        }


        @Override
        public void run() {
            while (!flag){
                int info;
                try {
                    info = blockingQueue.take();
                    System.out.println(Thread.currentThread().getName()+" --->consumer "+info);
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }


        }
        public void shutDown(){
            flag=true;
        }

        public static void main(String[] args) {
            BlockingQueue blockingQueue = new LinkedBlockingDeque(10);
            Producer producer = new Producer(blockingQueue);
            Consumer consumer = new Consumer(blockingQueue);
            //创建5个生产者,5个消费者
            for(int i = 0; i<10;i++){
                //System.out.println("-----------------------"+i+"-----------------------");
                if(i<5){
                    new Thread(producer,"producer"+i).start();
                }else{
                    new Thread(consumer,"consumer"+(i-5)).start();
                }

            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            producer.shutDown();
            consumer.shutDown();


        }
    }
}

输出

producer0---->Producer-1129494571
producer1---->Producer1335810196
producer2---->Producer251379931
producer3---->Producer-1038309758
producer4---->Producer1259289873
consumer0 --->consumer -1129494571
consumer1 --->consumer 1335810196
consumer2 --->consumer 251379931
consumer3 --->consumer -1038309758
consumer4 --->consumer 1259289873
producer0---->Producer2080589140
producer1---->Producer-226440319
producer3---->Producer-1251256190
producer2---->Producer1570622388
producer4---->Producer-1730471428
consumer1 --->consumer 2080589140
consumer0 --->consumer -226440319
consumer2 --->consumer -1251256190
consumer3 --->consumer 1570622388
consumer4 --->consumer -1730471428
producer1---->Producer-1117165496
producer0---->Producer1429895528
producer4---->Producer-12279844
producer2---->Producer1148382323
producer3---->Producer859079924
consumer0 --->consumer -1117165496
consumer1 --->consumer 1429895528
consumer2 --->consumer -12279844
consumer3 --->consumer 1148382323
consumer4 --->consumer 859079924
producer0---->Producer697920454
producer1---->Producer-1472263430
producer3---->Producer1862992273
producer2---->Producer-431825769
producer4---->Producer-170876869
consumer0 --->consumer -1472263430
consumer1 --->consumer 697920454
consumer2 --->consumer 1862992273
consumer3 --->consumer -431825769
consumer4 --->consumer -170876869
producer0---->Producer661728231
producer1---->Producer-1580613248
producer4---->Producer286944580
producer2---->Producer-1756199503
producer3---->Producer-515489831
consumer1 --->consumer 661728231
consumer0 --->consumer -1580613248
consumer3 --->consumer 286944580
consumer2 --->consumer -1756199503
consumer4 --->consumer -515489831
producer0---->Producer-824253958
producer1---->Producer-718043703
producer2---->Producer613726687
producer4---->Producer1562017654
producer3---->Producer2113604249
consumer3 --->consumer -718043703
consumer0 --->consumer -824253958
consumer1 --->consumer 613726687
consumer2 --->consumer 2113604249
consumer4 --->consumer 1562017654
producer1---->Producer-1926369295
producer0---->Producer1160592917
producer3---->Producer261832181
producer4---->Producer45296507
producer2---->Producer2027140406
consumer3 --->consumer -1926369295
consumer1 --->consumer 1160592917
consumer2 --->consumer 261832181
consumer0 --->consumer 45296507
consumer4 --->consumer 2027140406
producer1---->Producer268940344
producer0---->Producer-680320907
producer3---->Producer1376218456
producer4---->Producer-1303516038
producer2---->Producer-415045622
consumer3 --->consumer -680320907
consumer2 --->consumer 268940344
consumer1 --->consumer 1376218456
consumer0 --->consumer -1303516038
consumer4 --->consumer -415045622
producer1---->Producer-373379865
producer0---->Producer1045950051
producer3---->Producer-282195419
producer4---->Producer2072455342
producer2---->Producer730482583
consumer3 --->consumer 1045950051
consumer0 --->consumer -373379865
consumer1 --->consumer -282195419
consumer2 --->consumer 2072455342
consumer4 --->consumer 730482583
producer0---->Producer1099300076
producer1---->Producer-438856015
producer3---->Producer-827705749
producer4---->Producer-489876804
producer2---->Producer-770066015
consumer3 --->consumer 1099300076
consumer2 --->consumer -438856015
consumer0 --->consumer -489876804
consumer1 --->consumer -827705749
consumer4 --->consumer -770066015
producer3---->Producer796772527
producer4---->Producer-1424401866
producer1---->Producer2104464948
producer0---->Producer-843892940
producer2---->Producer167062848
consumer3 --->consumer -1424401866
consumer1 --->consumer 796772527
consumer0 --->consumer 2104464948
consumer2 --->consumer -843892940
consumer4 --->consumer 167062848
producer0---->Producer2062676055
producer1---->Producer-1075270028
producer4---->Producer830173242
producer3---->Producer-288128280
producer2---->Producer-1316693459
consumer3 --->consumer 2062676055
consumer2 --->consumer -1075270028
consumer1 --->consumer -1316693459
consumer0 --->consumer 830173242
consumer4 --->consumer -288128280
producer0---->Producer-1740245319
producer1---->Producer-2079049898
producer4---->Producer-1382219742
producer3---->Producer663598513
producer2---->Producer-1374412157
consumer3 --->consumer -1740245319
consumer4 --->consumer -2079049898
consumer0 --->consumer -1382219742
consumer1 --->consumer 663598513
consumer2 --->consumer -1374412157
producer3---->Producer923120722
producer4---->Producer1267254300
producer2---->Producer-355170922
producer0---->Producer-384775396
producer1---->Producer1978595907
consumer4 --->consumer -355170922
consumer3 --->consumer 923120722
consumer2 --->consumer 1267254300
consumer1 --->consumer 1978595907
consumer0 --->consumer -384775396
producer4---->Producer301647653
producer3---->Producer2070336417
consumer4 --->consumer 301647653
consumer3 --->consumer 2070336417
producer1---->Producer130543442
producer0---->Producer33891840
producer2---->Producer199012254
consumer2 --->consumer 130543442
consumer1 --->consumer 33891840
consumer0 --->consumer 199012254
producer4---->Producer2034412277
consumer3 --->consumer 2034412277
consumer4 --->consumer 1684896549
producer3---->Producer1684896549
producer2---->Producer-823024779
producer0---->Producer1245530223
producer1---->Producer1426270482
consumer2 --->consumer -823024779
consumer1 --->consumer 1245530223
consumer0 --->consumer 1426270482
consumer3 --->consumer -657670721
producer4---->Producer-657670721
consumer0 --->consumer -514396374
producer1---->Producer-514396374
consumer1 --->consumer -1938139766
producer0---->Producer-1938139766
consumer2 --->consumer -1416028874
producer2---->Producer-1416028874
producer3---->Producer386535270
consumer4 --->consumer 386535270
producer4---->Producer-280750862
consumer3 --->consumer -280750862
producer0---->Producer-1610461450
consumer1 --->consumer -1610461450
producer1---->Producer-906749135
consumer0 --->consumer -906749135
consumer4 --->consumer -1239123559
producer3---->Producer-1239123559
producer2---->Producer596392102
consumer2 --->consumer 596392102
producer4---->Producer144344294
consumer3 --->consumer 144344294
producer2---->Producer-239480864
consumer2 --->consumer -239480864
producer3---->Producer-1952232640
consumer4 --->consumer -1952232640
consumer0 --->consumer -138057655
producer1---->Producer-138057655
consumer1 --->consumer -1277497082
producer0---->Producer-1277497082

Process finished with exit code 0

即可看到生产者生产的 被消费者消费了,与普通队列不同的是
队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来

你可能感兴趣的:(Java阻塞队列的实现)