Java--concurrent並發包下阻塞隊列介紹

來源:互聯網
上載者:User

標籤:鏈表實現   exception   頭部   同步   mil   緩衝系統   數組   任務調度   lin   

JDK提供了7中阻塞隊列,這裡介紹其中3中,剩餘的以此類推原理相同。

1.ArrayBlockingQueue

package com.seeyon.queue;import java.util.concurrent.ArrayBlockingQueue;/** * Created by yangyu on 16/11/27. *//** * ArrayBlockingQueue是數組結構組成的有界阻塞隊列 * 當隊列已經滿了的時候,put操作會阻塞當前線程,直到隊列發生出隊操作然後會喚醒put線程在入隊 * 當隊列為空白的時候,take操作會阻塞當前線程,直到隊列發生入隊操作後會喚醒take線程進行出隊 */public class TestArrayBlockingQueue {    public static void main(String[] args) {        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue(1);        try {            queue.put("1111");            /**             * 該操作會被阻塞,知道隊列發生出隊操作             */            queue.put("2222");        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

 

2.LinkedBlockingQueue:鏈表實現的有界阻塞隊列

 

3.PriorityBlockingQueue:支援優先順序的無界阻塞隊列

 

4.DelayQueue

package com.seeyon.queue;import java.util.concurrent.DelayQueue;import java.util.concurrent.Delayed;import java.util.concurrent.TimeUnit;import static java.util.concurrent.TimeUnit.NANOSECONDS;/** * Created by yangyu on 16/11/27. *//** * DelayQueue是一個支援延時擷取元素的無界隊列 * DelayQueue可以用於如下情境: * 1.緩衝系統的的設計:用DelayQueue儲存緩衝元素的有效期間,用一個線程迴圈查詢DelayQueue,一旦能從DelayQueue中擷取到元素,說明該元素到期了 * 2.定時任務調度:使用DelayQueue儲存當天會執行的任務和執行時間,一旦從DelayQueue中擷取到任務就開始執行,TimerQueue就是使用DelayQueue實現的 * DelayQueue的原理: * 1.當線程put元素的時候,DelayQueue會對你put的元素通過其本身的compareTo方法進行排序,延時時間越短的順序越靠近隊列頭部 * 2.當線程take元素的時候,DelayQueue會檢測當前是否有Thread已經在等待隊頭元素了,如果有的話,那麼只能阻塞當前前程,等已經取到隊頭 * 的Thread完成以後再喚醒。 * 如果沒有Thread在等待隊頭元素的話,那麼會查詢一下隊頭元素還剩多少Delay時間,並且將當前線程設定為隊頭等待線程,然後讓當前線程wait剩餘 * Delay時間後在來擷取隊頭元素。 */public class TestDelayQueue {    public static void main(String[] args) {        DelayQueue<Message> delayQueue = new DelayQueue<>();        delayQueue.put(new Message(2000,"yangyu"));        try {            System.out.println(delayQueue.take());        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("end");    }    private static class Message implements Delayed{        private long nanoTime;        private String data;        Message(long millisTime ,String data){            this.nanoTime = now()+millisTime*(1000*1000);            this.data = data;        }        private final long now(){            return System.nanoTime();        }        @Override        public long getDelay(TimeUnit unit) {            return unit.convert(nanoTime - now(), NANOSECONDS);        }        @Override        public int compareTo(Delayed other) {            if (other == this) // compare zero if same object                return 0;            if (other instanceof Message) {                Message x = (Message) other;                long diff = nanoTime - x.nanoTime;                if (diff < 0)                    return -1;                else if (diff > 0)                    return 1;                else                    return 1;            }            long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS);            return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;        }    }}

 

5.SynchronousQueue

package com.seeyon.queue;import java.util.concurrent.SynchronousQueue;/** * Created by yangyu on 16/11/27. *//** * SynchronousQueue是一個不儲存資料的隊列,只是做資料的的傳遞工作 * 同步隊列,一個put操作必須等待一個take操作,否則線程被阻塞 * 同樣,一個take操作必須等待一個put操作,否則線程被阻塞 */public class TestSynchronousQueue {    public static void main(String[] args) {        SynchronousQueue<String> strings = new SynchronousQueue<>();        Thread t =new Thread(()->{            try {                /**                 * 該take操作會被阻塞,直到後面的strings.put("yangyu")操作後,當前線程才會被喚醒                 */                System.out.println(strings.take());            } catch (InterruptedException e) {                e.printStackTrace();            }        });        t.start();                try {            Thread.sleep(2000);            /**             * 喚醒阻塞線程並且傳遞資料             */            strings.put("yangyu");        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("完成");    }}

 

6.LinkedTransferQueue

 

7.LinkedBlockingDeqeue:是一個鏈表結構組成的雙向阻塞隊列,可以從隊列的兩端插入或者移出元素。

Java--concurrent並發包下阻塞隊列介紹

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.