zoukankan      html  css  js  c++  java
  • BlockingQueue中 take、offer、put、add的一些比较

    (转自:https://blog.csdn.net/wei_ya_wen/article/details/19344939 侵删)

    在java多线程操作中, BlockingQueue<E> 常用的一种方法之一。在看jdk内部尤其是一些多线程,大量使用了blockinkQueue 来做的。 

    借用jdk api解释下:

    BlockingQueue 方法以四种形式出现,对于不能立即满足但可能在将来某一时刻可以满足的操作,这四种形式的处理方式不同:第一种是抛出一个异常,第二种是返回一个特殊值(null 或 false,具体取决于操作),第三种是在操作可以成功前,无限期地阻塞当前线程,第四种是在放弃前只在给定的最大时间限制内阻塞。下表中总结了这些方法:

     抛出异常特殊值阻塞超时
    插入add(e)offer(e)put(e)offer(e, time, unit)
    移除remove()poll()take()poll(time, unit)
    检查element()peek()不可用不可用


    offer: 将指定元素插入此队列中(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则返回 false,不会抛异常:

    java源代码

    [html] view plain copy
    1. public boolean offer(E e) {  
    2.        if (e == null) throw new NullPointerException();  
    3.        final ReentrantLock lock = this.lock;  
    4.        lock.lock();  
    5.        try {  
    6.            if (count == items.length)  
    7.                return false;  
    8.            else {  
    9.                insert(e);  
    10.                return true;  
    11.            }  
    12.        } finally {  
    13.            lock.unlock();  
    14.        }  
    15.    }  

    put:

    将指定元素插入此队列中,将等待可用的空间.通俗点说就是>maxSize 时候,阻塞,直到能够有空间插入元素

    java源代码:

    [html] view plain copy
    1. public void put(E e) throws InterruptedException {  
    2.        if (e == null) throw new NullPointerException();  
    3.        final E[] items = this.items;  
    4.        final ReentrantLock lock = this.lock;  
    5.        lock.lockInterruptibly();  
    6.        try {  
    7.            try {  
    8.                while (count == items.length)  
    9.                    notFull.await();  
    10.            } catch (InterruptedException ie) {  
    11.                notFull.signal(); // propagate to non-interrupted thread  
    12.                throw ie;  
    13.            }  
    14.            insert(e);  
    15.        } finally {  
    16.            lock.unlock();  
    17.        }  
    18.    }  

    take: 获取并移除此队列的头部,在元素变得可用之前一直等待 。queue的长度 == 0 的时候,一直阻塞

    java 源代码:

    [html] view plain copy
    1. public E take() throws InterruptedException {  
    2.     final ReentrantLock lock = this.lock;  
    3.     lock.lockInterruptibly();  
    4.     try {  
    5.         try {  
    6.             while (count == 0)  
    7.                 notEmpty.await();  
    8.         } catch (InterruptedException ie) {  
    9.             notEmpty.signal(); // propagate to non-interrupted thread  
    10.             throw ie;  
    11.         }  
    12.         E x = extract();  
    13.         return x;  
    14.     } finally {  
    15.         lock.unlock();  
    16.     }  
    17. }  

    add: 和collection的add一样,没什么可以说的。如果当前没有可用的空间,则抛出 IllegalStateException



    例子如下:

    [html] view plain copy
    1.     public static void main(String[] args) {  
    2.         java.util.concurrent.Executor executor = Executors.newFixedThreadPool(10);  
    3.         Runnable task = new Runnable() {  
    4.               
    5.             @Override  
    6.             public void run() {  
    7.                 System.out.println("ggg");  
    8.             }  
    9.         };  
    10.         executor.execute(task);  
    11.         */  
    12.           
    13.          BlockingQueue q = new ArrayBlockingQueue(10);  
    14.          Producer p = new Producer(q);  
    15.          Consumer c1 = new Consumer(q);  
    16.          Consumer c2 = new Consumer(q);  
    17.          new Thread(p).start();  
    18.          new Thread(c1).start();  
    19.          new Thread(c2).start();  
    20.   
    21.     }  
    22. }  
    23.   
    24.   
    25. class Producer implements Runnable {  
    26.        private final BlockingQueue<Object> queue;  
    27.        Producer(BlockingQueue q) { queue = q; }  
    28.        public void run() {  
    29.          for(int i=0;i<100;i++){  
    30.              try {  
    31.                 queue.put(i);  
    32.             } catch (InterruptedException e1) {  
    33.                 // TODO Auto-generated catch block  
    34.                 e1.printStackTrace();  
    35.             }   
    36.              try {  
    37.                 Thread.sleep(20);  
    38.             } catch (InterruptedException e) {  
    39.                 // TODO Auto-generated catch block  
    40.                 e.printStackTrace();  
    41.             }  
    42.          }  
    43.        }  
    44.   
    45.      }  
    46.   
    47.      class Consumer implements Runnable {  
    48.        private final BlockingQueue queue;  
    49.        Consumer(BlockingQueue q) { queue = q; }  
    50.        public void run() {  
    51.          try {  
    52.            while(true) {   
    53.                consume(  
    54.                        queue.take()  
    55.                        );   
    56.                }  
    57.          } catch (InterruptedException ex) {  
    58.                
    59.          }  
    60.        }  
    61.        void consume(Object x) {  
    62.            System.out.println(x);  
    63.              
    64.        }  
    65.      }  
  • 相关阅读:
    实体ip 虚拟ip 固定ip 动态ip
    mysql数据库性能调优总结积累
    Java项目相关监控与调优
    线程锁与避免线程锁 线程锁检测
    在Eclipse中使用JUnit4进行单元测试(高级篇)
    MySQL性能优化的21条最佳经验【转】
    在Eclipse中使用JUnit4进行单元测试(中级篇)
    在Eclipse中使用JUnit4进行单元测试(初级篇)
    Windbg学习使用
    性能测试积累总结
  • 原文地址:https://www.cnblogs.com/lipengsheng-javaweb/p/12526316.html
Copyright © 2011-2022 走看看