ui设计较好的网站,wap网站怎么做,网店设计方案范文,广州市建设厅网站1. ArrayBlockingQueue, LinkedBlockingQueue, ConcurrentLinkedQueue ArrayBlockingQueue, LinkedBlockingQueue 继承自 BlockingQueue, 他们的特点就是 Blocking, Blocking 特有的方法就是 take() 和 put(), 这两个方法是阻塞方法, 每当队列容量满的时候, put() 方法就会进入…1. ArrayBlockingQueue, LinkedBlockingQueue, ConcurrentLinkedQueue ArrayBlockingQueue, LinkedBlockingQueue 继承自 BlockingQueue, 他们的特点就是 Blocking, Blocking 特有的方法就是 take() 和 put(), 这两个方法是阻塞方法, 每当队列容量满的时候, put() 方法就会进入wait, 直到队列空出来, 而每当队列为空时, take() 就会进入等待, 直到队列有元素可以 take() ArrayBlockingQueue, LinkedBlockingQueue 区别在于 ArrayBlockingQueue 必须指定容量, 且可以指定 fair 变量, 如果 fair 为 true, 则会保持 take() 或者 put() 操作时线程的 block 顺序, 先 block 的线程先 take() 或 put(), fair 又内部变量 ReentrantLock 保证 ConcurrentLinkedQueue 通过 CAS 操作实现了无锁的 poll() 和 offer(), 他的容量是动态的, 由于无锁, 所以在 poll() 或者 offer() 的时候 head 与 tail 可能会改变, 所以它会持续的判断 head 与 tail 是否改变来保证操作正确性, 如果改变, 则会重新选择 head 与 tail. 而由于无锁的特性, 他的元素更新与 size 变量更新无法做到原子 (实际上它没有 size 变量), 所以他的 size() 是通过遍历 queue 来获得的, 在效率上是 O(n), 而且无法保证准确性, 因为遍历的时候有可能 queue size 发生了改变. RingBuffer 是 Distruptor 中的一个用来替代 ArrayBlockingQueue 的队列, 它的思想在于长度可控, 且无锁, 只有在 blocking 的时候(没有数据的时候出队, 数据满的时候入队)会自旋. 实现原理是使用一个环形array, 生产者作为 tail, 消费者作为 head, 每生产一次 tail atomic, 每消费一次 head atomic, tail 不能超过 head 一圈(array size, 即队列满时 blocking), tail 不能超过自己tail一圈(即不能覆盖未被消费的值), head 不能超过 tail (即无可消费任务时 blocking), head 不能取到空值(取到空值时 blocking). blocking 使用一个 while 自旋来完成, 那么只要生产者消费者的速度相当时, 即可通过 atomicInteger(cas) 保证无锁, 而如果你需要在 blocking 的时候立即返回, 则 while 自旋都可以不需要. 相比于 ArrayBlockingQueue, 它可以绝大部分时间无锁, blocking 自旋, 相比于 concurrentLinkedQueue, 他又能做到长度限制. 代码如下: public class RingBufferT implements Serializable {/****/private static final long serialVersionUID 6976960108708949038L;private volatile AtomicInteger head;private volatile AtomicInteger tail;private int length;final T EMPTY null;private volatile T[] queue;public RingBuffer(ClassT type, int length){this.head new AtomicInteger(0);this.tail new AtomicInteger(0);this.length length 0 ? 2 16 : length; // 默认2^16 this.queue (T[]) Array.newInstance(type, this.length);}public void enQueue(T t){if(t null) t (T) new Object();// 阻塞 -- 避免多生成者循环生产同一个节点 while(this.getTail() - this.getHead() this.length);int ctail this.tail.getAndIncrement();while(this.queue[this.getTail(ctail)] ! EMPTY); // 自旋 this.queue[this.getTail(ctail)] t;}public T deQueue(){T t null;// 阻塞 -- 避免多消费者循环消费同一个节点 while(this.head.get() this.tail.get());int chead this.head.getAndIncrement();while(this.queue[this.getHead(chead)] EMPTY); // 自旋 t this.queue[this.getHead(chead)];this.queue[this.getHead(chead)] EMPTY;return t;}public int getHead(int index){return index (this.length - 1);}public int getTail(int index) {return index (this.length - 1);}public int getHead() {return head.get() (this.length - 1);}public int getTail() {return tail.get() (this.length - 1);}public T[] getQueue() {return queue;}public int getLength() {return length;}public void setLength(int length) {this.length length;}} 转载于:https://www.cnblogs.com/zemliu/p/3823597.html