1.ConcurrentLinkedQueue:是一个适用于高并发场景下链接节点的无界线程安全队列,基于cas支持高并发,非阻塞队列。
add方法:
public boolean add(E e) {
return offer(e);
}
public boolean offer(E e) {
//为空抛出异常
checkNotNull(e);
//创建新节点
final Node<E> newNode = new Node<E>(e);
//获取尾结点
for (Node<E> t = tail, p = t;;) {
//尾结点的下一节点 正常为null
Node<E> q = p.next;
//如果为null 自旋将新节点设置为尾结点 成功返回true
if (q == null) {
// p is last node
if (p.casNext(null, newNode)) {
// Successful CAS is the linearization point
// for e to become an element of this queue,
// and for newNode to become "live".
if (p != t) // hop two nodes at a time
casTail(t, newNode); // Failure is OK.
return true;
}
// Lost CAS race to another thread; re-read next
}
//并发条件下的处理 更新尾结点的值 赋值给p
else if (p == q)
// We have fallen off list. If tail is unchanged, it
// will also be off-list, in which case we need to
// jump to head, from which all live nodes are always
// reachable. Else the new tail is a better bet.
p = (t != (t = tail)) ? t : head;
else //否则 继续更新尾结点的值 赋值给p
// Check for tail updates after two hops.
p = (p != t && t != (t = tail)) ? t : q;
}
}
2.BlockingQueue:可以提供阻塞功能的队列。
提供方法:
入队 | 出队 | 查看 |
---|---|---|
add(e) 可能抛异常 | remove() 可能抛异常 | element() |
put(e) 可能阻塞 | take() 可能阻塞 | peek() |
offer(e)返回boolean | poll() | |
offer(e, timeout, unit)返回boolean | poll(timeout, unit) |
接口实现类包含:
ArrayBlockingQueue:有界限队列,初始化需要设定长度,基于ReentrantLock支持线程并发。
offer方法:检查是否为null,为空抛出异常,队列满返回false,否则入队列 返回true
public boolean offer(E e) {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
enqueue(e);
return true;
}
} finally {
lock.unlock();
}
}
LinkedBlockingQueue:无界队列,默认最大值为Integer.MAX_VALUE,也可以设定长度限制,基于AtomicInteger、ReentrantLock实现线程并发。
offer方法:检查是否为null,为空抛出异常,队列满返回false,否则入队列 返回true
public boolean offer(E e) {
if (e == null) throw new NullPointerException();
final AtomicInteger count = this.count;
if (count.get() == capacity)
return false;
int c = -1;
Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
if (count.get() < capacity) {
enqueue(node);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
}
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();
return c >= 0;
}
SynchronousQueue:无内容队列,容量为0,take和put必须同时出现,否则阻塞,用作线程间任务调度。基于cas实现线程安全。
示例代码:put和take缺少一个 都将一直自旋等待
BlockingQueue<String> synQueue = new SynchronousQueue<>();
new Thread(() ->{
try {
synQueue.put("1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() ->{
try {
System.out.println(synQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
PriorityBlockingQueue:基于优先级的无界阻塞队列,队列的对象必须实现Comparable接口,String,int等为自然顺序。基于ReentrantLock实现线程安全。
示例代码:
BlockingQueue proQueue = new PriorityBlockingQueue();
proQueue.offer(1);
proQueue.offer(3);
proQueue.offer(2);
//person类未实现Comparable 抛出异常
// proQueue.offer(new Person(1));
System.out.println(proQueue.poll());
System.out.println(proQueue.poll());
System.out.println(proQueue.poll());
class Person{
private int age ;
Person(int age){
this.age = age;
}
}
DelayQueue:时间排序无界队列,放入对象必须实现Delayed接口,基于ReentrantLock实现线程安全。
示例代码:
BlockingQueue<Timeer> proQueue = new DelayQueue();
long now = System.currentTimeMillis();
proQueue.put(new Timeer(now+1000,"t1"));
proQueue.put(new Timeer(now+5000,"t2"));
proQueue.put(new Timeer(now+500,"t3"));
System.out.println(proQueue.take());
System.out.println(proQueue.take());
System.out.println(proQueue.take());
class Timeer implements Delayed{
private String name;
private long time ;
Timeer(long time,String name){
this.time = time;
this.name = name;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(time - System.currentTimeMillis(),TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
if(this.getDelay(TimeUnit.MILLISECONDS)<o.getDelay(TimeUnit.MILLISECONDS)){
return -1;
} else if(this.getDelay(TimeUnit.MILLISECONDS)>o.getDelay(TimeUnit.MILLISECONDS)){
return 1;
}else{
return 0;
}
}
@Override
public String toString() {
return "Timeer{" +
"name='" + name + '\'' +
'}';
}
}
LinkedTransferQueue:链表结构组成的无界阻塞队列,基于LockSupport、cas实现线程并发安全。内含transfer入队方法,如果添加元素未出队则一直阻塞当前线程。
示例代码:
LinkedTransferQueue<String> linkedTransferQueue = new LinkedTransferQueue<>();
new Thread(() ->{
try {
System.out.println("我入队了");
linkedTransferQueue.transfer("a");
System.out.println("我出队了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() ->{
try {
//睡两秒后获取
TimeUnit.MILLISECONDS.sleep(2000);
linkedTransferQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
LinkedBlockingDeque:一个线程安全的双端队列实现,内部实现维护了前端和后端节点,基于ReentrantLock实现线程安全。
示例代码:
LinkedBlockingDeque linkedBlockingDeque =new LinkedBlockingDeque();
//添加头元素
linkedBlockingDeque.addFirst(1);
linkedBlockingDeque.addFirst(2);
linkedBlockingDeque.addFirst(3);
//添加尾元素
linkedBlockingDeque.addLast(4);
linkedBlockingDeque.addLast(5);
linkedBlockingDeque.addLast(6);
//取出尾元素
System.out.println(linkedBlockingDeque.pollLast());
//查看尾元素
System.out.println(linkedBlockingDeque.peekLast());
//取出尾元素
System.out.println(linkedBlockingDeque.pollLast());
//取出尾元素
System.out.println(linkedBlockingDeque.pollLast());//取出尾元素
System.out.println(linkedBlockingDeque.pollLast());//取出尾元素
System.out.println(linkedBlockingDeque.pollLast());//取出尾元素
System.out.println(linkedBlockingDeque.pollLast());//取出尾元素
System.out.println(linkedBlockingDeque.pollLast());