BlockingQueue
另一个Queue,它支持在检索元素时等待队列变为非空,以及在存储元素时等待队列中的空间变为可用的操作。
BlockingQueue方法有四种形式,有不同的处理操作的方式,这些操作不能立即被满足,但可能在将来的某个时候被满足:
第一个 抛出一个异常,
第二个 返回一个特殊值(根据操作的不同,可以是null或false)
第三个 无限期地阻塞当前线程,直到操作成功
第四个 在放弃之前只阻塞给定的最大时间限制。这些方法总结如下表:
BlockingQueueTest
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
class BlockingQueueTest {
public static void main(String[] args) throws InterruptedException {
//队列的大小
ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(arrayBlockingQueue.add("a"));
System.out.println(arrayBlockingQueue.add("b"));
System.out.println(arrayBlockingQueue.add("c"));
try {
//java.lang.IllegalStateException: Queue full
System.out.println(arrayBlockingQueue.add("d"));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("----------------------");
System.out.println(arrayBlockingQueue.remove());
System.out.println(arrayBlockingQueue.remove());
System.out.println(arrayBlockingQueue.remove());
try {
//java.util.NoSuchElementException
System.out.println(arrayBlockingQueue.remove());
} catch (Exception e) {
//抛出异常
e.printStackTrace();
}
TimeUnit.SECONDS.sleep(1);
System.out.println("==============第一阶段测试完毕==============");
arrayBlockingQueue = new ArrayBlockingQueue(3);
System.out.println(arrayBlockingQueue.offer("a"));
System.out.println(arrayBlockingQueue.offer("b"));
System.out.println(arrayBlockingQueue.offer("c"));
//offer 不抛出异常
System.out.println(arrayBlockingQueue.offer("d"));
System.out.println(arrayBlockingQueue.poll());
System.out.println(arrayBlockingQueue.poll());
System.out.println(arrayBlockingQueue.poll());
//null 不抛出异常
System.out.println(arrayBlockingQueue.poll());
TimeUnit.SECONDS.sleep(1);
System.out.println("==============第二阶段测试完毕==============");
arrayBlockingQueue = new ArrayBlockingQueue(3);
arrayBlockingQueue.put("a");
arrayBlockingQueue.put("b");
arrayBlockingQueue.put("c");
//队列没有位置就会阻塞
arrayBlockingQueue.put("c");
System.out.println(arrayBlockingQueue.take());
System.out.println(arrayBlockingQueue.take());
System.out.println(arrayBlockingQueue.take());
}
}
运行结果
true
truetrue
a
b
c
java.lang.IllegalStateException: Queue full
at java.util.AbstractQueue.add(AbstractQueue.java:98)
at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312)
at online.wenmeng.cloudfile.CyclicBarrierTests.main(CloudFileApplicationTests.java:17)
java.util.NoSuchElementException
at java.util.AbstractQueue.remove(AbstractQueue.java:117)
at online.wenmeng.cloudfile.CyclicBarrierTests.main(CloudFileApplicationTests.java:27)
第一阶段测试完毕
true
true
true
false
a
b
c
null
第二阶段测试完毕[第三阶段阻塞,导致没有输出,也不会运行完成]
SynchronousQueueTest
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
class SynchronousQueueTest {
public static void main(String[] args) throws InterruptedException {
SynchronousQueue<String> synchronousQueue = new SynchronousQueue<>(); //同步队列
//写线程
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + "put 1");
synchronousQueue.put("1");
System.out.println(Thread.currentThread().getName() + "put 2");
synchronousQueue.put("2");
System.out.println(Thread.currentThread().getName() + "put 3");
synchronousQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "T1").start();
//读线程
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "=>" + synchronousQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "=>" + synchronousQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "=>" + synchronousQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}, "T2").start();
}
}
运行结果
T1put 1
T2=>1
T1put 2
T2=>2
T1put 3
T2=>3