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<Integer> blockingQueue;
        //同步变量 volatile
        private volatile boolean flag;
        private Random random;

        public Producer(BlockingQueue<Integer> 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<Integer> blockingQueue;
        private volatile boolean flag;
        public Consumer(BlockingQueue<Integer> 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<Integer> blockingQueue = new LinkedBlockingDeque<Integer>(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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容