傻大方


首页 > 潮·科技 > >

阻塞队列(1)java 7 种BlockingQueue介绍( 二 )



按关键词阅读:

Java里的阻塞队列JDK7提供了7个阻塞队列 。
ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列 。
LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列 。
PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列 。
DelayQueue:一个使用优先级队列实现的无界阻塞队列 。
SynchronousQueue:一个不存储元素的阻塞队列 。
LinkedTransferQueue:一个由链表结构组成的无界阻塞队列 。
LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列 。
让我们后续一起集齐 7 颗龙珠 , 召唤神龙吧~
阻塞队列(1)java 7 种BlockingQueue介绍文章插图
7颗龙珠
ArrayBlockingQueueArrayBlockingQueue是一个用数组实现的有界阻塞队列 。 此队列按照先进先出(FIFO)的原则对元素进行排序 。 默认情况下不保证访问者公平的访问队列 , 所谓公平访问队列是指阻塞的所有生产者线程或消费者线程 , 当队列可用时 , 可以按照阻塞的先后顺序访问队列 , 即先阻塞的生产者线程 , 可以先往队列里插入元素 , 先阻塞的消费者线程 , 可以先从队列里获取元素 。
通常情况下为了保证公平性会降低吞吐量 。 我们可以使用以下代码创建一个公平的阻塞队列:
ArrayBlockingQueue fairQueue = newArrayBlockingQueue(1000,true);【阻塞队列(1)java 7 种BlockingQueue介绍】访问者的公平性是使用可重入锁实现的 , 代码如下
public ArrayBlockingQueue(int capacity, boolean fair) {if (capacity <= 0)throw new IllegalArgumentException();this.items = new Object[capacity];lock = new ReentrantLock(fair);notEmpty = lock.newCondition();notFull =lock.newCondition();}LinkedBlockingQueueLinkedBlockingQueue是一个用链表实现的有界阻塞队列 。 此队列的默认和最大长度为Integer.MAX_VALUE 。 此队列按照先进先出的原则对元素进行排序 。
PriorityBlockingQueuePriorityBlockingQueue是一个支持优先级的无界队列 。 默认情况下元素采取自然顺序排列 , 也可以通过比较器comparator来指定元素的排序规则 。 元素按照升序排列 。
DelayQueueDelayQueue是一个支持延时获取元素的无界阻塞队列 。 队列使用PriorityQueue来实现 。 队列中的元素必须实现Delayed接口 , 在创建元素时可以指定多久才能从队列中获取当前元素 。 只有在延迟期满时才能从队列中提取元素 。 我们可以将DelayQueue运用在以下应用场景:
缓存系统的设计:可以用DelayQueue保存缓存元素的有效期 , 使用一个线程循环查询DelayQueue , 一旦能从DelayQueue中获取元素时 , 表示缓存有效期到了 。 定时任务调度 。 使用DelayQueue保存当天将会执行的任务和执行时间 , 一旦从DelayQueue中获取到任务就开始执行 , 从比如TimerQueue就是使用DelayQueue实现的 。 队列中的Delayed必须实现compareTo来指定元素的顺序 。 比如让延时时间最长的放在队列的末尾 。 实现代码如下:
public int compareTo(Delayed other) {if (other == this) // compare zero ONLY if same objectreturn 0;if (other instanceof ScheduledFutureTask) {ScheduledFutureTask x = (ScheduledFutureTask)other;long diff = time - x.time;if (diff < 0)return -1;else if (diff > 0)return 1;else if (sequenceNumber < x.sequenceNumber)return -1;elsereturn 1;}long d = (getDelay(TimeUnit.NANOSECONDS) -other.getDelay(TimeUnit.NANOSECONDS));return (d == 0) ? 0 : ((d < 0) ? -1 : 1);}如何实现Delayed接口我们可以参考 ScheduledThreadPoolExecutor 里 ScheduledFutureTask 类 。
这个类实现了Delayed接口 。
首先:在对象创建的时候 , 使用time记录前对象什么时候可以使用 , 代码如下:
ScheduledFutureTask(Runnable r, V result, long ns, long period) {super(r, result);this.time = ns;this.period = period;this.sequenceNumber = sequencer.getAndIncrement();}然后使用getDelay可以查询当前元素还需要延时多久 , 代码如下:
public long getDelay(TimeUnit unit) {return unit.convert(time - now(), TimeUnit.NANOSECONDS);}通过构造函数可以看出延迟时间参数ns的单位是纳秒 , 自己设计的时候最好使用纳秒 , 因为getDelay时可以指定任意单位 , 一旦以纳秒作为单位 , 而延时的时间又精确不到纳秒就麻烦了 。
使用时请注意当time小于当前时间时 , getDelay会返回负数 。
如何实现延时队列延时队列的实现很简单 , 当消费者从队列里获取元素时 , 如果元素没有达到延时时间 , 就阻塞当前线程 。
long delay = first.getDelay(TimeUnit.NANOSECONDS);if (delay <= 0)return q.poll();else if (leader != null)available.await();SynchronousQueueSynchronousQueue 是一个不存储元素的阻塞队列 。


稿源:(未知)

【傻大方】网址:http://www.shadafang.com/c/111J30XH020.html

标题:阻塞队列(1)java 7 种BlockingQueue介绍( 二 )


上一篇:屏幕上|男子花1000元买报废苹果X, 本以为亏大了, 结果却很意外

下一篇:ARGON18|新款ARGON18全能向公路车上市 更硬更持久