java BlockingQueue之ArrayBlockingQueue
来源:互联网 发布:素数判断 c语言 编辑:程序博客网 时间:2024/04/28 16:27
JAVA API中这样解释BlockingQueue:
支持两个附加操作的 Queue
,这两个操作是:获取元素时等待队列变为非空,以及存储元素时等待空间变得可用。
BlockingQueue 方法以四种形式出现,对于不能立即满足但可能在将来某一时刻可以满足的操作,这四种形式的处理方式不同:第一种是抛出一个异常,第二种是返回一个特殊值(null 或false,具体取决于操作),第三种是在操作可以成功前,无限期地阻塞当前线程,第四种是在放弃前只在给定的最大时间限制内阻塞。下表中总结了这些方法:
抛出异常特殊值阻塞超时插入add(e)
offer(e)
put(e)
offer(e, time, unit)
移除remove()
poll()
take()
poll(time, unit)
检查element()
peek()
不可用不可用BlockingQueue 不接受 null 元素。试图 add、put 或 offer 一个 null 元素时,某些实现会抛出 NullPointerException。null 被用作指示poll 操作失败的警戒值。
先看一个简单的实现例子:
public class BoundedBuffer { //可中断同步锁 final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } }}
上面的例子展示了一个定长的队列,提供了存放和提取数据的方法,且使用ReentrantLock来实现同步。
再来看看SUN的实现:
private static final long serialVersionUID = -817911632652898426L; private final E[] items; private int takeIndex; private int putIndex; private int count; private final ReentrantLock lock; private final Condition notEmpty; private final Condition notFull;
public ArrayBlockingQueue(int paramInt) { this(paramInt, false); } //初始构造函数 public ArrayBlockingQueue(int paramInt, boolean paramBoolean) { if (paramInt <= 0) throw new IllegalArgumentException(); this.items = ((Object[])new Object[paramInt]); //初始化锁对象 this.lock = new ReentrantLock(paramBoolean); this.notEmpty = this.lock.newCondition(); this.notFull = this.lock.newCondition(); } //put的实现 public void put(E paramE) throws InterruptedException { if (paramE == null) throw new NullPointerException(); Object[] arrayOfObject = this.items; ReentrantLock localReentrantLock = this.lock; //如果当前线程未被中断则获取锁 localReentrantLock.lockInterruptibly(); try { try { while (this.count == arrayOfObject.length) //数组已满 等待直到被唤醒或中断 this.notFull.await(); } catch (InterruptedException localInterruptedException) { //被中断则唤醒 this.notFull.signal(); throw localInterruptedException; } insert(paramE); } finally { localReentrantLock.unlock(); } } private void insert(E paramE) { this.items[this.putIndex] = paramE; this.putIndex = inc(this.putIndex); this.count += 1; //唤醒持有notEmpty等待的线程 this.notEmpty.signal(); } public E take() throws InterruptedException { ReentrantLock localReentrantLock = this.lock; //获取锁 localReentrantLock.lockInterruptibly(); try { try { while (this.count == 0) //空则等待 this.notEmpty.await(); } catch (InterruptedException localInterruptedException) { //唤醒 this.notEmpty.signal(); throw localInterruptedException; } Object localObject1 = extract(); Object localObject2 = localObject1; return localObject2; } finally { localReentrantLock.unlock(); } } private E extract() { Object[] arrayOfObject = this.items; Object localObject = arrayOfObject[this.takeIndex]; arrayOfObject[this.takeIndex] = null; this.takeIndex = inc(this.takeIndex); this.count -= 1; //唤醒等待的线程 this.notFull.signal(); return localObject; }
public ArrayBlockingQueue(int paramInt) { this(paramInt, false); } //初始构造函数 public ArrayBlockingQueue(int paramInt, boolean paramBoolean) { if (paramInt <= 0) throw new IllegalArgumentException(); this.items = ((Object[])new Object[paramInt]); //初始化锁对象 this.lock = new ReentrantLock(paramBoolean); this.notEmpty = this.lock.newCondition(); this.notFull = this.lock.newCondition(); } //put的实现 public void put(E paramE) throws InterruptedException { if (paramE == null) throw new NullPointerException(); Object[] arrayOfObject = this.items; ReentrantLock localReentrantLock = this.lock; //如果当前线程未被中断则获取锁 localReentrantLock.lockInterruptibly(); try { try { while (this.count == arrayOfObject.length) //数组已满 等待直到被唤醒或中断 this.notFull.await(); } catch (InterruptedException localInterruptedException) { //被中断则唤醒 this.notFull.signal(); throw localInterruptedException; } insert(paramE); } finally { localReentrantLock.unlock(); } } private void insert(E paramE) { this.items[this.putIndex] = paramE; this.putIndex = inc(this.putIndex); this.count += 1; //唤醒持有notEmpty等待的线程 this.notEmpty.signal(); } public E take() throws InterruptedException { ReentrantLock localReentrantLock = this.lock; //获取锁 localReentrantLock.lockInterruptibly(); try { try { while (this.count == 0) //空则等待 this.notEmpty.await(); } catch (InterruptedException localInterruptedException) { //唤醒 this.notEmpty.signal(); throw localInterruptedException; } Object localObject1 = extract(); Object localObject2 = localObject1; return localObject2; } finally { localReentrantLock.unlock(); } } private E extract() { Object[] arrayOfObject = this.items; Object localObject = arrayOfObject[this.takeIndex]; arrayOfObject[this.takeIndex] = null; this.takeIndex = inc(this.takeIndex); this.count -= 1; //唤醒等待的线程 this.notFull.signal(); return localObject; }
以上只贴出了部分源码,ArrayBlockingQueue还提供了其他三种处理方式,有兴趣的可以自己去研读。
下面是一个小例子:
public class Setup { class Producer implements Runnable { volatile int i=0; private final BlockingQueue<String> queue; public Producer(BlockingQueue<String> q) { queue = q; } public void run() { try { while(true&&i<1000) { queue.put(produce()); } } catch (InterruptedException ex) { ex.printStackTrace(); } } String produce(){ i++; return "put"+i; } } class Consumer implements Runnable { private final BlockingQueue<String> queue; Consumer(BlockingQueue<String> q) { queue = q; } public void run() { try { while(true) { synchronized (lock) { System.out.println(queue.take()); } } } catch (InterruptedException ex) { ex.printStackTrace(); } } } Object lock = new Object(); public static void main(String args[]){ Setup s = new Setup(); BlockingQueue<String> q = new ArrayBlockingQueue<String>(1); Producer p = s.new Producer(q); Consumer c1 = s.new Consumer(q); Consumer c2 = s.new Consumer(q); new Thread(p).start(); new Thread(c1).start(); new Thread(c2).start(); }}
- java BlockingQueue之ArrayBlockingQueue
- 《Java源码分析》:BlockingQueue之ArrayBlockingQueue
- java.util.concurrent.BlockingQueue ArrayBlockingQueue
- java 并发工具包 BlockingQueue-ArrayBlockingQueue
- BlockingQueue arrayBlockingqueue
- BlockingQueue、ArrayBlockingQueue
- 多线程之阻塞队列ArrayBlockingQueue,BlockingQueue
- 浅谈JDK BlockingQueue的实现类之ArrayBlockingQueue
- SynchronousQueue/BlockingQueue/ArrayBlockingQueue区别
- Java 多线程应用 之 ArrayBlockingQueue
- JAVA阻塞队列之ArrayBlockingQueue
- Java并发容器之ArrayBlockingQueue
- java源码阅读之ArrayBlockingQueue
- Java多线程之BlockingQueue
- Java多线程之BlockingQueue
- java concurent之BlockingQueue
- JAVA多线程之BlockingQueue
- Java并发之BlockingQueue
- Mac OS X 安装 OpenCV2.4.3【详述】
- 【java】走进JVM,浅水也能摸鱼
- Struts2中jsp前台传值到action后台的三种方式
- 学籍管理系统
- redis主从配置
- java BlockingQueue之ArrayBlockingQueue
- android 特殊字符 处理
- Tracert和Ping的命令区别
- android 模拟器输入中文
- iOS安全攻防(一):Hack必备的命令与工具
- linux下文件的权限
- 百度地图从零学起(一)初识百度地图
- 提高显示布局文件的性能 3 - 按需载入视图(ViewStub的使用方法)
- 解决LoadRunner超时错误