国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

java 隊(duì)列

goji / 1326人閱讀

摘要:是基于鏈接節(jié)點(diǎn)的線程安全的隊(duì)列。通過(guò)這些高效并且線程安全的隊(duì)列類,為我們快速搭建高質(zhì)量的多線程程序帶來(lái)極大的便利。隊(duì)列內(nèi)部?jī)H允許容納一個(gè)元素。該隊(duì)列的頭部是延遲期滿后保存時(shí)間最長(zhǎng)的元素。

隊(duì)列簡(jiǎn)述

Queue: 基本上,一個(gè)隊(duì)列就是一個(gè)先入先出(FIFO)的數(shù)據(jù)結(jié)構(gòu)
Queue接口與List、Set同一級(jí)別,都是繼承了Collection接口。LinkedList實(shí)現(xiàn)了Deque接 口。
在并發(fā)隊(duì)列上JDK提供了兩套實(shí)現(xiàn),一個(gè)是以ConcurrentLinkedQueue為代表的高性能隊(duì)列非阻塞,一個(gè)是以BlockingQueue接口為代表的阻塞隊(duì)列,無(wú)論哪種都繼承自Queue

阻塞隊(duì)列與非阻塞隊(duì)列

阻塞隊(duì)列與普通隊(duì)列的區(qū)別在于,當(dāng)隊(duì)列是空的時(shí),從隊(duì)列中獲取元素的操作將會(huì)被阻塞,或者當(dāng)隊(duì)列是滿時(shí),往隊(duì)列里添加元素的操作會(huì)被阻塞。試圖從空的阻塞隊(duì)列中獲取元素的線程將會(huì)被阻塞,直到其他的線程往空的隊(duì)列插入新的元素。同樣,試圖往已滿的阻塞隊(duì)列中添加新元素的線程同樣也會(huì)被阻塞,直到其他的線程使隊(duì)列重新變得空閑起來(lái),如從隊(duì)列中移除一個(gè)或者多個(gè)元素,或者完全清空隊(duì)列


(圖片來(lái)自網(wǎng)絡(luò)https://www.cnblogs.com/lemon...)

非阻塞隊(duì)列

沒(méi)有實(shí)現(xiàn)的阻塞接口的LinkedList: 實(shí)現(xiàn)了java.util.Queue接口和java.util.AbstractQueue接口

內(nèi)置的不阻塞隊(duì)列: PriorityQueue 和 ConcurrentLinkedQueue

PriorityQueue 和 ConcurrentLinkedQueue 類在 Collection Framework 中加入兩個(gè)具體集合實(shí)現(xiàn)。

PriorityQueue 類實(shí)質(zhì)上維護(hù)了一個(gè)有序列表。加入到 Queue 中的元素根據(jù)它們的天然排序(通過(guò)其 java.util.Comparable 實(shí)現(xiàn))或者根據(jù)傳遞給構(gòu)造函數(shù)的 java.util.Comparator 實(shí)現(xiàn)來(lái)定位。

ConcurrentLinkedQueue 是基于鏈接節(jié)點(diǎn)的、線程安全的隊(duì)列。并發(fā)訪問(wèn)不需要同步。因?yàn)樗陉?duì)列的尾部添加元素并從頭部刪除它們,所以只要不需要知道隊(duì)列的大小,ConcurrentLinkedQueue 對(duì)公共集合的共享訪問(wèn)就可以工作得很好。收集關(guān)于隊(duì)列大小的信息會(huì)很慢,需要遍歷隊(duì)列。

ConcurrentLinkedQueue : 是一個(gè)適用于高并發(fā)場(chǎng)景下的隊(duì)列,通過(guò)無(wú)鎖的方式,實(shí)現(xiàn)
了高并發(fā)狀態(tài)下的高性能,通常ConcurrentLinkedQueue性能好于BlockingQueue.它
是一個(gè)基于鏈接節(jié)點(diǎn)的無(wú)界線程安全隊(duì)列。該隊(duì)列的元素遵循先進(jìn)先出的原則。頭是最先
加入的,尾是最近加入的,該隊(duì)列不允許null元素。

ConcurrentLinkedQueue重要方法:
add 和offer() 都是加入元素的方法(在ConcurrentLinkedQueue中這倆個(gè)方法沒(méi)有任何區(qū)別)
poll() 和peek() 都是取頭元素節(jié)點(diǎn),區(qū)別在于前者會(huì)刪除元素,后者不會(huì)。

ConcurrentLinkedQueue例子
@RequestMapping("test-clq")
    public void testConcurrentLinkedQueue() {
        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque<>();
        q.offer("Java");
        q.offer("C#");
        q.offer("Javascript");
        q.offer("Python");
        // 從頭獲取元素,刪除該元素
        System.out.println(q.poll());
        // 從頭獲取元素,不刪除該元素
        System.out.println(q.peek());
        // 獲取總長(zhǎng)度
        System.out.println(q.size());
        // 遍歷
        for (String s : q) {
            System.out.println(s);
        }
    }

結(jié)果:
Java
C#
3
C#
Javascript
Python

BlockingQueue

阻塞隊(duì)列,顧名思義,首先它是一個(gè)隊(duì)列,通過(guò)一個(gè)共享的隊(duì)列,可以使得數(shù)據(jù)由隊(duì)列的一端輸入,從另外一端輸出;
常用的隊(duì)列主要有以下兩種:(當(dāng)然通過(guò)不同的實(shí)現(xiàn)方式,還可以延伸出很多不同類型的隊(duì)列,DelayQueue就是其中的一種)

先進(jìn)先出(FIFO):先插入的隊(duì)列的元素也最先出隊(duì)列,類似于排隊(duì)的功能。從某種程度上來(lái)說(shuō)這種隊(duì)列也體現(xiàn)了一種公平性。

后進(jìn)先出(LIFO):后插入隊(duì)列的元素最先出隊(duì)列,這種隊(duì)列優(yōu)先處理最近發(fā)生的事件。

多線程環(huán)境中,通過(guò)隊(duì)列可以很容易實(shí)現(xiàn)數(shù)據(jù)共享,比如經(jīng)典的“生產(chǎn)者”和“消費(fèi)者”模型中,通過(guò)隊(duì)列可以很便利地實(shí)現(xiàn)兩者之間的數(shù)據(jù)共享。假設(shè)我們有若干生產(chǎn)者線程,另外又有若干個(gè)消費(fèi)者線程。如果生產(chǎn)者線程需要把準(zhǔn)備好的數(shù)據(jù)共享給消費(fèi)者線程,利用隊(duì)列的方式來(lái)傳遞數(shù)據(jù),就可以很方便地解決他們之間的數(shù)據(jù)共享問(wèn)題。但如果生產(chǎn)者和消費(fèi)者在某個(gè)時(shí)間段內(nèi),萬(wàn)一發(fā)生數(shù)據(jù)處理速度不匹配的情況呢?理想情況下,如果生產(chǎn)者產(chǎn)出數(shù)據(jù)的速度大于消費(fèi)者消費(fèi)的速度,并且當(dāng)生產(chǎn)出來(lái)的數(shù)據(jù)累積到一定程度的時(shí)候,那么生產(chǎn)者必須暫停等待一下(阻塞生產(chǎn)者線程),以便等待消費(fèi)者線程把累積的數(shù)據(jù)處理完畢,反之亦然。然而,在concurrent包發(fā)布以前,在多線程環(huán)境下,我們每個(gè)程序員都必須去自己控制這些細(xì)節(jié),尤其還要兼顧效率和線程安全,而這會(huì)給我們的程序帶來(lái)不小的復(fù)雜度。好在此時(shí),強(qiáng)大的concurrent包橫空出世了,而他也給我們帶來(lái)了強(qiáng)大的BlockingQueue。(在多線程領(lǐng)域:所謂阻塞,在某些情況下會(huì)掛起線程(即阻塞),一旦條件滿足,被掛起的線程又會(huì)自動(dòng)被喚醒)

阻塞隊(duì)列(BlockingQueue)是一個(gè)支持兩個(gè)附加操作的隊(duì)列。這兩個(gè)附加的操作是:
在隊(duì)列為空時(shí),獲取元素的線程會(huì)等待隊(duì)列變?yōu)榉强铡?br>當(dāng)隊(duì)列滿時(shí),存儲(chǔ)元素的線程會(huì)等待隊(duì)列可用。
阻塞隊(duì)列常用于生產(chǎn)者和消費(fèi)者的場(chǎng)景,生產(chǎn)者是往隊(duì)列里添加元素的線程,消費(fèi)者是從隊(duì)列里拿元素的線程。阻塞隊(duì)列就是生產(chǎn)者存放元素的容器,而消費(fèi)者也只從容器里拿元素。
BlockingQueue即阻塞隊(duì)列,從阻塞這個(gè)詞可以看出,在某些情況下對(duì)阻塞隊(duì)列的訪問(wèn)可能會(huì)造成阻塞。被阻塞的情況主要有如下兩種:

當(dāng)隊(duì)列滿了的時(shí)候進(jìn)行入隊(duì)列操作

當(dāng)隊(duì)列空了的時(shí)候進(jìn)行出隊(duì)列操作

因此,當(dāng)一個(gè)線程試圖對(duì)一個(gè)已經(jīng)滿了的隊(duì)列進(jìn)行入隊(duì)列操作時(shí),它將會(huì)被阻塞,除非有另一個(gè)線程做了出隊(duì)列操作;同樣,當(dāng)一個(gè)線程試圖對(duì)一個(gè)空隊(duì)列進(jìn)行出隊(duì)列操作時(shí),它將會(huì)被阻塞,除非有另一個(gè)線程進(jìn)行了入隊(duì)列操作。
在Java中,BlockingQueue的接口位于java.util.concurrent 包中(在Java5版本開(kāi)始提供),由上面介紹的阻塞隊(duì)列的特性可知,阻塞隊(duì)列是線程安全的。
在新增的Concurrent包中,BlockingQueue很好的解決了多線程中,如何高效安全“傳輸”數(shù)據(jù)的問(wèn)題。通過(guò)這些高效并且線程安全的隊(duì)列類,為我們快速搭建高質(zhì)量的多線程程序帶來(lái)極大的便利。

下表顯示了jdk1.5中的阻塞隊(duì)列的操作:

  add 增加一個(gè)元索 如果隊(duì)列已滿,則拋出一個(gè)IIIegaISlabEepeplian異常
  remove 移除并返回隊(duì)列頭部的元素 如果隊(duì)列為空,則拋出一個(gè)NoSuchElementException異常
  element 返回隊(duì)列頭部的元素 如果隊(duì)列為空,則拋出一個(gè)NoSuchElementException異常
  offer 添加一個(gè)元素并返回true 如果隊(duì)列已滿,則返回false
  poll 移除并返問(wèn)隊(duì)列頭部的元素 如果隊(duì)列為空,則返回null
  peek 返回隊(duì)列頭部的元素 如果隊(duì)列為空,則返回null
  put 添加一個(gè)元素 如果隊(duì)列滿,則阻塞
  take 移除并返回隊(duì)列頭部的元素 如果隊(duì)列為空,則阻塞

阻塞隊(duì)列操作:
aad、remove和element操作在你試圖為一個(gè)已滿的隊(duì)列增加元素或從空隊(duì)列取得元素時(shí) 拋出異常
offer、poll、peek方法。這些方法在無(wú)法完成任務(wù)時(shí),只是給出一個(gè)出錯(cuò)提示而不會(huì)拋出異常
阻塞操作put和take。put方法在隊(duì)列滿時(shí)阻塞,take方法在隊(duì)列空時(shí)阻塞。

ArrayBlockingQueue

ArrayBlockingQueue是一個(gè)有邊界的阻塞隊(duì)列,它的內(nèi)部實(shí)現(xiàn)是一個(gè)數(shù)組。有邊界的意思是它的容量是有限的,我們必須在其初始化的時(shí)候指定它的容量大小,容量大小一旦指定就不可改變。
ArrayBlockingQueue是以先進(jìn)先出的方式存儲(chǔ)數(shù)據(jù),最新插入的對(duì)象是尾部,最新移出的對(duì)象是頭部

LinkedBlockingQueue

LinkedBlockingQueue阻塞隊(duì)列大小的配置是可選的,如果我們初始化時(shí)指定一個(gè)大小,它就是有邊界的,如果不指定,它就是無(wú)邊界的。說(shuō)是無(wú)邊界,其實(shí)是采用了默認(rèn)大小為Integer.MAX_VALUE的容量 。它的內(nèi)部實(shí)現(xiàn)是一個(gè)鏈表。
和ArrayBlockingQueue一樣,LinkedBlockingQueue 也是以先進(jìn)先出的方式存儲(chǔ)數(shù)據(jù),最新插入的對(duì)象是尾部,最新移出的對(duì)象是頭部。

PriorityBlockingQueue

PriorityBlockingQueue是一個(gè)沒(méi)有邊界的隊(duì)列,它的排序規(guī)則和 java.util.PriorityQueue一樣。需要注意,PriorityBlockingQueue中允許插入null對(duì)象。
所有插入PriorityBlockingQueue的對(duì)象必須實(shí)現(xiàn) java.lang.Comparable接口,隊(duì)列優(yōu)先級(jí)的排序規(guī)則就是按照我們對(duì)這個(gè)接口的實(shí)現(xiàn)來(lái)定義的。
另外,我們可以從PriorityBlockingQueue獲得一個(gè)迭代器Iterator,但這個(gè)迭代器并不保證按照優(yōu)先級(jí)順序進(jìn)行迭代。

SynchronousQueue

SynchronousQueue隊(duì)列內(nèi)部?jī)H允許容納一個(gè)元素。當(dāng)一個(gè)線程插入一個(gè)元素后會(huì)被阻塞,除非這個(gè)元素被另一個(gè)線程消費(fèi)

DelayQueue

(基于PriorityQueue來(lái)實(shí)現(xiàn)的)是一個(gè)存放Delayed 元素的無(wú)界阻塞隊(duì)列,只有在延遲期滿時(shí)才能從中提取元素。該隊(duì)列的頭部是延遲期滿后保存時(shí)間最長(zhǎng)的 Delayed 元素。如果延遲都還沒(méi)有期滿,則隊(duì)列沒(méi)有頭部,并且poll將返回null。當(dāng)一個(gè)元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一個(gè)小于或等于零的值時(shí),則出現(xiàn)期滿,poll就以移除這個(gè)元素了。此隊(duì)列不允許使用 null 元素。

使用BlockingQueue模擬生產(chǎn)者與消費(fèi)者

生產(chǎn)者

public class ProducerThread implements Runnable {
    private BlockingQueue queue;
    private AtomicInteger count = new AtomicInteger();
    private volatile boolean FLAG = true;

    public ProducerThread(BlockingQueue queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "生產(chǎn)者開(kāi)始啟動(dòng)....");
        while (FLAG) {
            String data = count.incrementAndGet() + "";
            try {
                boolean offer = queue.offer(data, 2, TimeUnit.SECONDS);
                if (offer) {
                    System.out.println(Thread.currentThread().getName() + ",生產(chǎn)隊(duì)列" + data + "成功..");
                } else {
                    System.out.println(Thread.currentThread().getName() + ",生產(chǎn)隊(duì)列" + data + "失敗..");
                }
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + ",生產(chǎn)者線程停止...");
    }

    public void stop() {
        this.FLAG = false;
    }

}

消費(fèi)者

public class ConsumerThread implements Runnable {
    private volatile boolean FLAG = true;
    private BlockingQueue blockingQueue;

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

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "消費(fèi)者開(kāi)始啟動(dòng)....");
        while (FLAG) {
            try {
                String data = blockingQueue.poll(2, TimeUnit.SECONDS);
                if (data == null || data == "") {
                    FLAG = false;
                    System.out.println("消費(fèi)者超過(guò)2秒時(shí)間未獲取到消息.");
                    return;
                }
                System.out.println("消費(fèi)者獲取到隊(duì)列信息成功,data:" + data);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

請(qǐng)求

@RequestMapping("test-blockingQueue")
    public void testBlockingQueue() {
        LinkedBlockingDeque blockingDeque = new LinkedBlockingDeque<>(1);
        ProducerThread producerThread = new ProducerThread(blockingDeque);
        ConsumerThread consumerThread = new ConsumerThread(blockingDeque);
        Thread t1 = new Thread(producerThread, "生產(chǎn)者");
        Thread t2 = new Thread(consumerThread, "消費(fèi)者");
        t1.start();
        t2.start();

        // 10秒后停止線程
        try {
            Thread.sleep(10 * 1000);
            producerThread.stop();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

結(jié)果

消費(fèi)者消費(fèi)者開(kāi)始啟動(dòng)....
生產(chǎn)者生產(chǎn)者開(kāi)始啟動(dòng)....
生產(chǎn)者,生產(chǎn)隊(duì)列1成功..
消費(fèi)者獲取到隊(duì)列信息成功,data:1
生產(chǎn)者,生產(chǎn)隊(duì)列2成功..
消費(fèi)者獲取到隊(duì)列信息成功,data:2
生產(chǎn)者,生產(chǎn)隊(duì)列3成功..
消費(fèi)者獲取到隊(duì)列信息成功,data:3
生產(chǎn)者,生產(chǎn)隊(duì)列4成功..
消費(fèi)者獲取到隊(duì)列信息成功,data:4
生產(chǎn)者,生產(chǎn)隊(duì)列5成功..
消費(fèi)者獲取到隊(duì)列信息成功,data:5
生產(chǎn)者,生產(chǎn)隊(duì)列6成功..
消費(fèi)者獲取到隊(duì)列信息成功,data:6
生產(chǎn)者,生產(chǎn)隊(duì)列7成功..
消費(fèi)者獲取到隊(duì)列信息成功,data:7
生產(chǎn)者,生產(chǎn)隊(duì)列8成功..
消費(fèi)者獲取到隊(duì)列信息成功,data:8
生產(chǎn)者,生產(chǎn)隊(duì)列9成功..
消費(fèi)者獲取到隊(duì)列信息成功,data:9
生產(chǎn)者,生產(chǎn)隊(duì)列10成功..
消費(fèi)者獲取到隊(duì)列信息成功,data:10
生產(chǎn)者,生產(chǎn)者線程停止...
消費(fèi)者超過(guò)2秒時(shí)間未獲取到消息.

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/74729.html

相關(guān)文章

  • Java知識(shí)點(diǎn)總結(jié)(Java容器-Queue)

    摘要:知識(shí)點(diǎn)總結(jié)容器知識(shí)點(diǎn)總結(jié)容器接口與是在同一級(jí)別,都是繼承了接口。另一種隊(duì)列則是雙端隊(duì)列,支持在頭尾兩端插入和移除元素,主要包括。一個(gè)由鏈表結(jié)構(gòu)組成的無(wú)界阻塞隊(duì)列。是一個(gè)阻塞的線程安全的隊(duì)列,底層實(shí)現(xiàn)也是使用鏈?zhǔn)浇Y(jié)構(gòu)。 Java知識(shí)點(diǎn)總結(jié)(Java容器-Queue) @(Java知識(shí)點(diǎn)總結(jié))[Java, Java容器] Queue Queue接口與List、Set是在同一級(jí)別,都是繼承了...

    hedzr 評(píng)論0 收藏0
  • [Java并發(fā)-6]“管程”-java管程初探

    摘要:語(yǔ)言在之前,提供的唯一的并發(fā)原語(yǔ)就是管程,而且之后提供的并發(fā)包,也是以管程技術(shù)為基礎(chǔ)的。但是管程更容易使用,所以選擇了管程。線程進(jìn)入條件變量的等待隊(duì)列后,是允許其他線程進(jìn)入管程的。并發(fā)編程里兩大核心問(wèn)題互斥和同步,都可以由管程來(lái)幫你解決。 并發(fā)編程這個(gè)技術(shù)領(lǐng)域已經(jīng)發(fā)展了半個(gè)世紀(jì)了。有沒(méi)有一種核心技術(shù)可以很方便地解決我們的并發(fā)問(wèn)題呢?這個(gè)問(wèn)題, 我會(huì)選擇 Monitor(管程)技術(shù)。Ja...

    Steve_Wang_ 評(píng)論0 收藏0
  • 什么是阻塞隊(duì)列?如何使用阻塞隊(duì)列來(lái)實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者模型?

    摘要:什么是阻塞隊(duì)列阻塞隊(duì)列是一個(gè)在隊(duì)列基礎(chǔ)上又支持了兩個(gè)附加操作的隊(duì)列。阻塞隊(duì)列的應(yīng)用場(chǎng)景阻塞隊(duì)列常用于生產(chǎn)者和消費(fèi)者的場(chǎng)景,生產(chǎn)者是向隊(duì)列里添加元素的線程,消費(fèi)者是從隊(duì)列里取元素的線程。由鏈表結(jié)構(gòu)組成的無(wú)界阻塞隊(duì)列。 什么是阻塞隊(duì)列? 阻塞隊(duì)列是一個(gè)在隊(duì)列基礎(chǔ)上又支持了兩個(gè)附加操作的隊(duì)列。 2個(gè)附加操作: 支持阻塞的插入方法:隊(duì)列滿時(shí),隊(duì)列會(huì)阻塞插入元素的線程,直到隊(duì)列不滿。 支持阻塞的...

    jemygraw 評(píng)論0 收藏0
  • Java 隊(duì)列

    摘要:隊(duì)列中有元素時(shí),就說(shuō)明有過(guò)期了,線程繼續(xù)執(zhí)行,然后元素出隊(duì),根據(jù)相應(yīng)的移除緩存。所以嚴(yán)格來(lái)說(shuō),雖然實(shí)現(xiàn)了隊(duì)列接口,但是它的目的卻并不是隊(duì)列,而是將生產(chǎn)者消費(fèi)者線程配對(duì)。轉(zhuǎn)移隊(duì)列鏈?zhǔn)睫D(zhuǎn)移隊(duì)列。 引言 本周在編寫短信驗(yàn)證碼頻率限制切面的時(shí)候,經(jīng)潘老師給的實(shí)現(xiàn)思路,使用隊(duì)列進(jìn)行實(shí)現(xiàn)。 看了看java.util包下的Queue接口,發(fā)現(xiàn)還從來(lái)沒(méi)用過(guò)呢! Collection集合類接口,由它派生...

    Pocher 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<