BlockingQueue阻塞队列
BlockingQueue
- 实现类
- Collection->Queue->BlockingQueue
- 使用场景:多线程并发处理,线程池
- Queue源码
public interface Queue<E> extends Collection<E> {
boolean add(E e);
boolean offer(E e);
E remove();
E poll();
E element();
E peek();
}
- BlockingQueue源码
public interface BlockingQueue<E> extends Queue<E> {
boolean add(E e);
boolean offer(E e);
void put(E e) throws InterruptedException;
boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;
E take() throws InterruptedException;
E poll(long timeout, TimeUnit unit)
throws InterruptedException;
int remainingCapacity();
boolean remove(Object o);
boolean contains(Object o);
int drainTo(Collection<? super E> c);
int drainTo(Collection<? super E> c, int maxElements);
}
ArrayBlockingQueue
- 依赖AQS实现并发操作
- 四组API
方式 | 抛出异常 | 不抛出异常 | 阻塞等待 | 超时等待 |
---|---|---|---|---|
添加 | add(o) | offer(o) | put(o) | offer(o, timeout, timeunit) |
移除 | remove() | poll() | take() | poll(timeout, timeunit) |
判断队首 | element() | peek() | --- | --- |
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
class MyBlockingQueue {
public static void main(String[] args) throws InterruptedException {
// 抛出异常
// test1();
// 不抛出异常
// test2();
// 阻塞等待
// test3();
// 超时等待
test4();
}
public static void test1() {
// 队列大小
ArrayBlockingQueue<Object> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(arrayBlockingQueue.add("a")); // true
System.out.println(arrayBlockingQueue.add("b")); // true
System.out.println(arrayBlockingQueue.add("c")); // true
// System.out.println(arrayBlockingQueue.add("d")); // IllegalStateException队列满
System.out.println(arrayBlockingQueue.element()); // 查看队首
System.out.println(arrayBlockingQueue.remove()); // ture
System.out.println(arrayBlockingQueue.remove()); // ture
System.out.println(arrayBlockingQueue.remove()); // ture
// System.out.println(arrayBlockingQueue.remove()); // NoSuchElementException
}
public static void test2() {
// 队列大小
ArrayBlockingQueue<Object> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(arrayBlockingQueue.offer("a"));
System.out.println(arrayBlockingQueue.offer("b"));
System.out.println(arrayBlockingQueue.offer("c"));
System.out.println(arrayBlockingQueue.offer("d")); // 不跑出异常,返回false
System.out.println(arrayBlockingQueue.peek());
System.out.println(arrayBlockingQueue.poll());
System.out.println(arrayBlockingQueue.poll());
System.out.println(arrayBlockingQueue.poll());
System.out.println(arrayBlockingQueue.poll()); // 不抛出异常,返回null
}
public static void test3() throws InterruptedException {
// 队列大小
ArrayBlockingQueue<Object> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
// 没有返回值
arrayBlockingQueue.put("a");
arrayBlockingQueue.put("b");
arrayBlockingQueue.put("c");
// arrayBlockingQueue.put("d");// 会一直等
System.out.println(arrayBlockingQueue.take()); // a
System.out.println(arrayBlockingQueue.take()); // b
System.out.println(arrayBlockingQueue.take()); // c
// System.out.println(arrayBlockingQueue.take());// 会一直等
}
public static void test4() throws InterruptedException {
// 队列大小
ArrayBlockingQueue<Object> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
arrayBlockingQueue.offer("a");
arrayBlockingQueue.offer("b");
arrayBlockingQueue.offer("c");
arrayBlockingQueue.offer("d", 2, TimeUnit.SECONDS);// 两秒后结束等待
System.out.println(arrayBlockingQueue.poll()); // a
System.out.println(arrayBlockingQueue.poll()); // b
System.out.println(arrayBlockingQueue.poll()); // c
System.out.println(arrayBlockingQueue.poll(2, TimeUnit.SECONDS)); // 两秒后结束等待,返回null
System.out.println("over");
}
}
SynchronousQueue同步队列
-
使用CAS实现线程的安全访问
-
构造函数,默认非公平
public SynchronousQueue() {
this(false);
}
public SynchronousQueue(boolean fair) {
// 公平:队尾匹配队头出队
// 非公平:先入栈后匹配
transferer = fair ? new TransferQueue<E>() : new TransferStack<E>();
}
- 它一种阻塞队列,其中每个 put 必须等待一个 take,反之亦然。同步队列没有任何内部容量,甚至连一个队列的容量都没有。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
class MySynchronousQueue {
public static void main(String[] args) {
// 同步队列
BlockingQueue<String> blockingQueue = new SynchronousQueue<>();
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " put\t1");
// 往queue放进去一个element以后就一直wait直到有其他thread进来把这个element取走
blockingQueue.put("1");
System.out.println(Thread.currentThread().getName() + " put\t2");
blockingQueue.put("2");
System.out.println(Thread.currentThread().getName() + " put\t3");
blockingQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Producer").start();
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
// 取出并删除element,取不到东西他会一直等
System.out.println(Thread.currentThread().getName() + " take\t" +blockingQueue.take());
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + " take\t" +blockingQueue.take());
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + " take\t" +blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Consumer").start();
}
}
LinkedBlockingQueue
- 构造函数Integer.MAX_VALUE
// 默认容量
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new Node<E>(null);
}
PriorityBlockingQueue
- 带优先级的无界阻塞队列
- 每次出队都返回优先级最高的元素,是二叉树最小堆的实现