试图从空的阻寨队列中获取元素的线程将会被阻寨,直到其他的线程往空的队列插入新的元素。同样 ·
试图往已满的阻寨队列中添加新元素的线程同样也会被阻寨,直到其他的线程从列中移除一个或者多个元素或者完全清空队列后使队列重新变得空闲起来并后续新增
抛出异常: add,remove方法,如果队列满还add,如果队列空还remove 就抛出异常
public static void main(String[] args) {
BlockingQueue<String> blockingQueue=new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
//用add方法如果超过预先定义的3个元素会抛出异常
System.out.println(blockingQueue.add("x"));
}
//执行结果
true
true
true
Exception in thread "main" java.lang.IllegalStateException: Queue full
at java.util.AbstractQueue.add(AbstractQueue.java:98)
at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312)
at com.hy.controller.ResController.main(ResController.java:942)
特殊值
public static void main(String[] args) {
BlockingQueue<String> blockingQueue=new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
//用offer方法如果超过预先定义的3个元素会返回false
System.out.println(blockingQueue.offer("x"));
//返回队列头元素
System.out.println(blockingQueue.peek());
//用poll方法 从空的阻寨队列中获取元素返回null
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
}
//执行结果
true
true
true
false
a
a
b
c
null
阻塞:
超时:
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> blockingQueue=new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a",2, TimeUnit.SECONDS));
System.out.println(blockingQueue.offer("b",2, TimeUnit.SECONDS));
System.out.println(blockingQueue.offer("c",2, TimeUnit.SECONDS));
//用offer方法如果超过预先定义的3个元素会返回false
System.out.println("等两秒钟===============");
System.out.println(blockingQueue.offer("x",2, TimeUnit.SECONDS));
}
//执行结果
true
true
true
等两秒钟===============
false
SynchronousQueue: 没有容量。 同步队列没有容量.
与其他BlockingQueue不同,SynchronousQueue是一个不存储元素的BlockingQuege。
每一个put操作必须要等待一个take操作,否则不能继续添加元素,反之亦然。
示例代码:
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> blockingQueue=new SynchronousQueue<>();
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"\tput 1");
blockingQueue.put("1");
System.out.println(Thread.currentThread().getName()+"\tput 2");
blockingQueue.put("2");
System.out.println(Thread.currentThread().getName()+"\tput 3");
blockingQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1").start();
new Thread(()->{
try {
Thread.sleep(5);
System.out.println(Thread.currentThread().getName()+"\t取出:"+blockingQueue.take());
Thread.sleep(5);
System.out.println(Thread.currentThread().getName()+"\t取出:"+blockingQueue.take());
Thread.sleep(5);
System.out.println(Thread.currentThread().getName()+"\t取出:"+blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t2").start();
}
//执行结果
t1 put 1
t2 取出:1
t1 put 2
t2 取出:2
t1 put 3
t2 取出:3
题 目:一个初始值为零的变量,两个线程对其交替操作,一个加1,一个减1
防止虚假唤醒机制
示例代码:
class ShareData{
private int number=0;
private Lock lock=new ReentrantLock();
private Condition condition=lock.newCondition();
public void increment() {
lock.lock();
try {
//1 判断 用while不用if ,为了避免虚假唤醒
while (number!=0){
//2 等待,不能生产
condition.await();
}
//2 干活
number++;
System.out.println(Thread.currentThread().getName()+"\t"+number);
//3 通知唤醒
condition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void dncrement() {
lock.lock();
try {
//1 判断
while (number==0){
//2 等待,不能生产
condition.await();
}
//2 干活
number--;
System.out.println(Thread.currentThread().getName()+"\t"+number);
//3 通知唤醒
condition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
//执行结果
aa 1
bb 0
aa 1
bb 0
aa 1
bb 0
aa 1
bb 0
aa 1
bb 0