• Java并发之BlockingQueue 阻塞队列(ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、SynchronousQueue)


      1 package com.thread.test.thread;
      2 import java.util.Random;
      3 import java.util.concurrent.*;
      4 
      5 /**
      6  * Created by windwant on 2016/5/26.
      7  */
      8 public class MyBlockingQueue {
      9     public static void main(String[] args) throws InterruptedException {
     10         testArrayBlockingQueue();
     11     }
     12 
     13     /**
     14      * 公平性 构造函数 true
     15      */
     16     public static void testArrayBlockingQueue(){
     17         BlockingQueue<String> abq = new ArrayBlockingQueue<String>(5);
     18         ExecutorService es = Executors.newCachedThreadPool();
     19         es.execute(new MyPro(abq, 1000));
     20         es.execute(new MyCus(abq, 5000));
     21         es.shutdown();
     22     }
     23 
     24     /**
     25      * 基于链表节点的可设置容量的队列,先进先出,队尾插入元素,队首获取元素。
     26      * 链表队列比基于数据的队列有更高的存取效率,但是在并发应用中效率无法预测。
     27      */
     28     public static void testLinkedBlockingQueue(){
     29         BlockingQueue<String> abq = new LinkedBlockingQueue<String>(5);
     30         ExecutorService es = Executors.newCachedThreadPool();
     31         es.execute(new MyPro(abq, 20));
     32         es.execute(new MyCus(abq, 2000));
     33         es.shutdown();
     34     }
     35 
     36     /**
     37      * DelayQueue
     38      * 无容量限制的阻塞队列,元素包含延迟时限,只有到达时限,元素才能被取出。
     39      * 队列顶部是距离到期时间最远的元素。
     40      * 如果所有的元素都未到期,将会返回null。
     41      * 元素在执行getDelay()方法返回值小于等于0时过期,即使没有被通过take或者poll执行提取,它们也会被当作一般元素对待。
     42      * 队列size方法返回所有元素的数量。
     43      * 队列不能包含null元素。
     44      */
     45     public static void testDelayQueue() throws InterruptedException {
     46         DelayQueue<MyDelayItem> dq = new DelayQueue<MyDelayItem>();
     47         ExecutorService es = Executors.newFixedThreadPool(5);
     48         es.execute(new MyDelayPro(dq, 1000));
     49         es.execute(new MyDelayCus(dq, 10000));
     50         es.shutdown();
     51     }
     52 
     53     /**
     54      * 无容量限制的阻塞队列,元素顺序维持策略同PriorityQueue一样,支持阻塞获取
     55      * 不允许添加null元素
     56      * 元素必须支持排序
     57      * 支持集合遍历,排序
     58      */
     59     public static void testPriorityBlockingQueue() throws InterruptedException {
     60         PriorityBlockingQueue<MyPriorityItem> pbq = new PriorityBlockingQueue<MyPriorityItem>();
     61         ExecutorService es = Executors.newFixedThreadPool(5);
     62         es.execute(new MyPriorityBlockingQueuePro(pbq, 1000));
     63         es.execute(new MyPriorityBlockingQueueCus(pbq, 10000));
     64         es.shutdown();
     65     }
     66 
     67     /**
     68      * 阻塞队列,插入元素和提取元素必须同步。
     69      * 异步队列没有容量的概念。
     70      * 无法使用peek,因为只有当你尝试移除时,元素才会存在。
     71      * 无法插入元素,除非有另外一个线程同时尝试获取元素。
     72      * 不支持遍历操作,因为队列中根本没有元素。
     73      * 队列的顶部就是尝试插入元素的线程要插入的元素。
     74      * 如果没有尝试插入元素的线程,那么就不存在能够提取的元素,poll会返回null。
     75      * 集合操作contains返null
     76      * 不允许插入null元素
     77      * */
     78     public static void testSynchronousQueue() throws InterruptedException {
     79         SynchronousQueue<String> sq = new SynchronousQueue<String>();
     80         ExecutorService es = Executors.newFixedThreadPool(5);
     81         es.execute(new MySynchronousQueuePro(sq, 1000));
     82         es.execute(new MySynchronousQueueCus(sq, 2000));
     83         es.shutdown();
     84     }
     85 }
     86 
     87 /**
     88  * 测试生产者
     89  */
     90 class MyPro implements Runnable{
     91 
     92     private BlockingQueue<String> bq;
     93 
     94     private int period = 1000;
     95 
     96     private Random r = new Random();
     97     MyPro(BlockingQueue bq, int period){
     98         this.bq = bq;
     99         this.period = period;
    100     }
    101 
    102     public void run() {
    103         try{
    104             while (true){
    105                 Thread.sleep(period);
    106                 String value = String.valueOf(r.nextInt(100));
    107                 if(bq.offer(value)){ //offer 能够插入就返回true,否则返回false
    108                     System.out.println("pro make value: " + value + " queue : " + bq.toString());
    109                     System.out.println("******************************************************");
    110                 }
    111             }
    112         }catch (InterruptedException e){
    113             e.printStackTrace();
    114         }
    115     }
    116 }
    117 
    118 /**
    119  * 测试消费者
    120  */
    121 class MyCus implements Runnable{
    122 
    123     private BlockingQueue<String> bq;
    124 
    125     private int period = 1000;
    126 
    127     private Random r = new Random();
    128     MyCus(BlockingQueue bq, int period){
    129         this.bq = bq;
    130         this.period = period;
    131     }
    132 
    133     public void run() {
    134         try{
    135             while (true){
    136                 Thread.sleep(period);
    137                 String value = bq.take(); //获取队列头部元素,无元素则阻塞
    138                 System.out.println("cus take value: " + value + " queue : " + bq.toString());
    139                 System.out.println("======================================================");
    140             }
    141         }catch (InterruptedException e){
    142             e.printStackTrace();
    143         }
    144     }
    145 }
    146 
    147 /**
    148  * 延迟队列元素 实现排序
    149  */
    150 class MyDelayItem implements Delayed{
    151 
    152     private long liveTime;
    153 
    154     private long removeTime;
    155 
    156     MyDelayItem(long liveTime, long removeTime){
    157         this.liveTime = liveTime;
    158         this.removeTime = TimeUnit.MILLISECONDS.convert(liveTime, TimeUnit.MILLISECONDS) + System.nanoTime();
    159     }
    160 
    161     public long getDelay(TimeUnit unit) {
    162         return unit.convert(removeTime - System.nanoTime(), unit);
    163     }
    164 
    165     public int compareTo(Delayed o) {
    166         if(o == null) return -1;
    167         if(o == this) return 0;
    168         if(o instanceof MyDelayItem){
    169             MyDelayItem tmp = (MyDelayItem) o;
    170             if(liveTime > tmp.liveTime){
    171                 return 1;
    172             }else if(liveTime == tmp.liveTime){
    173                 return 0;
    174             }else{
    175                 return -1;
    176             }
    177         }
    178         long diff = getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS);
    179         return diff > 0 ? 1 : diff == 0 ? 0 : -1;
    180     }
    181 
    182     public String toString(){
    183         return "{livetime: " + String.valueOf(liveTime) + ", removetime: " + String.valueOf(removeTime) + "}";
    184     }
    185 }
    186 
    187 /**
    188  * 延迟队列测试生产者
    189  */
    190 class MyDelayPro implements Runnable{
    191 
    192     private DelayQueue<MyDelayItem> dq;
    193 
    194     private int period = 1000;
    195 
    196     private Random r = new Random();
    197 
    198     MyDelayPro(DelayQueue dq, int period){
    199         this.dq = dq;
    200         this.period = period;
    201     }
    202     public void run() {
    203         try{
    204             while (true){
    205                 Thread.sleep(period);
    206                 if(dq.size() > 5){
    207                     continue;
    208                 }
    209                 MyDelayItem di = new MyDelayItem(r.nextInt(10), r.nextInt(10));
    210                 dq.offer(di);
    211                 System.out.println("delayqueue: add---" + di.toString() + "size: " + dq.size());
    212                 System.out.println("*************************************");
    213             }
    214         }catch (InterruptedException e){
    215             e.printStackTrace();
    216         }
    217     }
    218 }
    219 
    220 /**
    221  * 延迟队列测试消费者
    222  */
    223 class MyDelayCus implements Runnable{
    224 
    225     private DelayQueue<MyDelayItem> dq;
    226 
    227     private int period = 1000;
    228 
    229     MyDelayCus(DelayQueue dq, int period){
    230         this.dq = dq;
    231         this.period = period;
    232     }
    233     public void run() {
    234         try{
    235             while (true){
    236                 Thread.sleep(period);
    237                 MyDelayItem di = dq.take();
    238                 System.out.println("delayqueue: remove---" + di.toString());
    239                 System.out.println("delayqueue: ---" + dq.toString());
    240                 System.out.println("======================================");
    241             }
    242         }catch (InterruptedException e){
    243             e.printStackTrace();
    244         }
    245     }
    246 }
    247 
    248 /**
    249  * 延迟队列元素 时限排序对比延迟队列
    250  */
    251 class MyPriorityItem implements Comparable<MyPriorityItem> {
    252 
    253     private int priority;
    254 
    255     MyPriorityItem(int priority){
    256         this.priority = priority;
    257     }
    258 
    259     /**
    260      * 数字大优先级高
    261      * @param o
    262      * @return
    263      */
    264     public int compareTo(MyPriorityItem o) {
    265         if(o == null) return -1;
    266         if(o == this) return 0;
    267         if(priority > o.priority){
    268             return -1;
    269         }else if(priority == o.priority){
    270             return 0;
    271         }else{
    272             return 1;
    273         }
    274     }
    275 
    276     public String toString(){
    277         return "{priority: " + String.valueOf(priority) + "}";
    278     }
    279 }
    280 
    281 /**
    282  * 优先队列测试生产者
    283  */
    284 class MyPriorityBlockingQueuePro implements Runnable{
    285 
    286     private PriorityBlockingQueue<MyPriorityItem> pbq;
    287 
    288     private int period = 1000;
    289 
    290     private Random r = new Random();
    291 
    292     MyPriorityBlockingQueuePro(PriorityBlockingQueue pbq, int period){
    293         this.pbq = pbq;
    294         this.period = period;
    295     }
    296     public void run() {
    297         try{
    298             while (true){
    299                 Thread.sleep(period);
    300                 if(pbq.size() > 5){
    301                     continue;
    302                 }
    303                 MyPriorityItem pi = new MyPriorityItem(r.nextInt(10));
    304                 pbq.offer(pi);
    305                 System.out.println("PriorityBlockingQueue: add---" + pi.toString() + " size: " + pbq.size());
    306                 System.out.println("PriorityBlockingQueue: " + pbq.toString());
    307                 System.out.println("*************************************");
    308             }
    309         }catch (InterruptedException e){
    310             e.printStackTrace();
    311         }
    312     }
    313 }
    314 
    315 /**
    316  * 优先队列测试消费者
    317  */
    318 class MyPriorityBlockingQueueCus implements Runnable{
    319 
    320     private PriorityBlockingQueue<MyPriorityItem> pbq;
    321 
    322     private int period = 1000;
    323 
    324     private Random r = new Random();
    325 
    326     MyPriorityBlockingQueueCus(PriorityBlockingQueue pbq, int period){
    327         this.pbq = pbq;
    328         this.period = period;
    329     }
    330     public void run() {
    331         try{
    332             while (true){
    333                 Thread.sleep(period);
    334                 MyPriorityItem di = pbq.take();
    335                 System.out.println("PriorityBlockingQueue: remove---" + di.toString());
    336                 System.out.println("PriorityBlockingQueue: ---" + pbq.toString());
    337                 System.out.println("======================================");
    338             }
    339         }catch (InterruptedException e){
    340             e.printStackTrace();
    341         }
    342     }
    343 }
    344 
    345 /**
    346  * 阻塞队列测试生产者
    347  */
    348 class MySynchronousQueuePro implements Runnable{
    349 
    350     private SynchronousQueue<String> sq;
    351 
    352     private int period = 1000;
    353 
    354     private Random r = new Random();
    355     MySynchronousQueuePro(SynchronousQueue sq, int period){
    356         this.sq = sq;
    357         this.period = period;
    358     }
    359 
    360     public void run() {
    361         try{
    362             while (true){
    363                 Thread.sleep(period);
    364                 String value = String.valueOf(r.nextInt(100));
    365                 if(sq.offer(value)) {
    366                     System.out.println("pro make value: " + value + " synchronous :" + sq.toString());
    367                     System.out.println("******************************************************");
    368                 }
    369             }
    370         }catch (InterruptedException e){
    371             e.printStackTrace();
    372         }
    373     }
    374 }
    375 
    376 /**
    377  * 阻塞队列测试消费者
    378  */
    379 class MySynchronousQueueCus implements Runnable{
    380 
    381     private BlockingQueue<String> sq;
    382 
    383     private int period = 1000;
    384 
    385     MySynchronousQueueCus(BlockingQueue sq, int period){
    386         this.sq = sq;
    387         this.period = period;
    388     }
    389 
    390     public void run() {
    391         try{
    392             while (true){
    393                 Thread.sleep(period);
    394                 String value = sq.take();
    395                 System.out.println("cus take value: " + value + " synchronous :" + sq.toString());
    396                 System.out.println("======================================================");
    397             }
    398         }catch (InterruptedException e){
    399             e.printStackTrace();
    400         }
    401     }
    402 }

    项目地址:https://github.com/windwant/windwant-demo/tree/master/thread-demo

  • 相关阅读:
    20190922 模拟
    poj3417 Network/闇の連鎖[树上差分]
    poj3280 Cheapest Palindrome[区间DP]
    poj3691 DNA repair[DP+AC自动机]
    BZOJ1030 [JSOI2007]文本生成器[DP+AC自动机]
    loj2424 「NOIP2015」子串[字符串DP]
    poj1038 Bugs Integrated, Inc.[状压DP]
    第05组 Beta冲刺 (2/5)(组长)
    第05组 Beta冲刺 (1/5)(组长)
    第05组 Alpha冲刺 总结(组长)
  • 原文地址:https://www.cnblogs.com/niejunlei/p/5984871.html
Copyright © 2020-2023  润新知