阻塞队列之PriorityBlockingQueue
来源:互联网 发布:java write 编辑:程序博客网 时间:2024/06/07 01:53
public class PriorityBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.SerializablePriorityBlockingQueue是一个无界的阻塞队列,排序规则和PriorityQueue一样,但只是逻辑上无界,因为尝试添加可能会因资源耗尽(OutOfMermoryError)而失败。
该类不能添加null元素,会抛出NullPointerException;不能插入没有实现Comparable(不可比较的对象),会抛出ClassCastException。
该类使用数组实现的二叉堆实现了优先级队列,同时增加了ReentrantLock锁实现阻塞达到线程安全。
1,初始容量为11,,扩容方法:
private void tryGrow(Object[] array, int oldCap) { lock.unlock(); // must release and then re-acquire main lock Object[] newArray = null; if (allocationSpinLock == 0 && UNSAFE.compareAndSwapInt(this, allocationSpinLockOffset, 0, 1)) { try { int newCap = oldCap + ((oldCap < 64) ? (oldCap + 2) : // grow faster if small (oldCap >> 1)); if (newCap - MAX_ARRAY_SIZE > 0) { // possible overflow int minCap = oldCap + 1; if (minCap < 0 || minCap > MAX_ARRAY_SIZE) throw new OutOfMemoryError(); newCap = MAX_ARRAY_SIZE; } if (newCap > oldCap && queue == array) newArray = new Object[newCap]; } finally { allocationSpinLock = 0; } } if (newArray == null) // back off if another thread is allocating Thread.yield(); lock.lock(); if (newArray != null && queue == array) { queue = newArray; System.arraycopy(array, 0, newArray, 0, oldCap); }}当旧容量小于64时,新容量=旧容量*2+2;大于64时,新容量 = 1.5*旧容量。之后还要看师傅超出最大容量。
2,入队offer()的逻辑和PriorityQueue一样,只是加了锁来实现线程安全。
public boolean offer(E e) { if (e == null) throw new NullPointerException(); final ReentrantLock lock = this.lock; lock.lock(); //增加了锁 int n, cap; Object[] array; while ((n = size) >= (cap = (array = queue).length)) tryGrow(array, cap); try { Comparator<? super E> cmp = comparator; if (cmp == null) siftUpComparable(n, e, array); else siftUpUsingComparator(n, e, array, cmp); size = n + 1; notEmpty.signal(); } finally { lock.unlock(); } return true;}
private static <T> void siftUpComparable(int k, T x, Object[] array) { Comparable<? super T> key = (Comparable<? super T>) x; while (k > 0) { int parent = (k - 1) >>> 1; Object e = array[parent]; if (key.compareTo((T) e) >= 0) break; array[k] = e; k = parent; } array[k] = key;}
public E poll() { final ReentrantLock lock = this.lock; lock.lock(); try { return dequeue(); } finally { lock.unlock(); }}public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); E result; try { while ( (result = dequeue()) == null) notEmpty.await(); } finally { lock.unlock(); } return result;}
private E dequeue() { int n = size - 1; if (n < 0) return null; else { Object[] array = queue; E result = (E) array[0]; E x = (E) array[n]; array[n] = null; Comparator<? super E> cmp = comparator; if (cmp == null) siftDownComparable(0, x, array, n); else siftDownUsingComparator(0, x, array, n, cmp); size = n; return result; }}
private static <T> void siftDownComparable(int k, T x, Object[] array, int n) { if (n > 0) { Comparable<? super T> key = (Comparable<? super T>)x; int half = n >>> 1; // loop while a non-leaf while (k < half) { int child = (k << 1) + 1; // assume left child is least Object c = array[child]; int right = child + 1; if (right < n && ((Comparable<? super T>) c).compareTo((T) array[right]) > 0) c = array[child = right]; if (key.compareTo((T) c) <= 0) break; array[k] = c; k = child; } array[k] = key; }}
阅读全文
0 0
- 阻塞队列之PriorityBlockingQueue
- JDK源码分析之主要阻塞队列实现类PriorityBlockingQueue
- 五 : PriorityBlockingQueue 优先级阻塞队列
- 阻塞queue系列之PriorityBlockingQueue
- 一心多用多线程-阻塞队列(2)-PriorityBlockingQueue
- 具有优先级的阻塞队列 PriorityBlockingQueue
- 【死磕Java并发】-----J.U.C之阻塞队列:PriorityBlockingQueue
- 并发队列-无界阻塞优先级队列PriorityBlockingQueue原理探究
- PriorityBlockingQueue 优先级阻塞队列的介绍和使用
- (十六)java多线程之优先队列PriorityBlockingQueue
- 进阶篇:优先级队列之PriorityBlockingQueue(十五)
- 优先级队列PriorityBlockingQueue
- java PriorityBlockingQueue 基础的优先级队列,可阻塞的读取操作.
- 阻塞队列之实战
- 阻塞队列之SynchronousQueue
- 阻塞队列之LinkedTransferQueue
- 阻塞队列之ArrayBlockingQueue
- 阻塞队列之ArrayBlockingQueue
- java---栈---顺序存储
- Notification--------通知的基本用法
- android EditText 的不可编辑可点击
- js用构造函数的方法创建数组
- JavaScript专题之数组去重
- 阻塞队列之PriorityBlockingQueue
- 实现一个递归算法
- 分布式缓存Redis Centos下单节点安装
- Java集合Colleciton接口
- Qt5.8 QTableView的应用(Qss美化,加checkbox)
- 不用计算设置水平垂直居中
- 隐藏手机号中间4位数 正则表达式
- javamail的配置过程
- golang的交叉编译