队列:FIFO(先进先出)
阻塞:
- 写入:如果队列满了,就必须阻塞等待
-
读取:如果队列为空,必须阻塞等待生产。
1605668690(1).jpg
图片.png
图片.png
ArrayBlockingQueue的四种API
示例1:(会抛出异常)
/**
*会抛出异常
*/
public static void test1(){
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
//System.out.println(blockingQueue.add("d")); //报异常:IllegalStateException: Queue full
System.out.println(blockingQueue.element()); //查看队首元素
System.out.println("============================");
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
//System.out.println(blockingQueue.remove()); //报异常:NoSuchElementException
}
示例2:(有返回值,不会抛出异常)
public static void test2(){
//队列大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d")); //false 不抛出异常
System.out.println(blockingQueue.peek()); //查看队首元素
System.out.println("============================");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll()); //null
}
返回值:
true
true
true
false
============================
a
b
c
null
示例3:等待,阻塞(一直阻塞)
public static void test3() throws InterruptedException {
//队列大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
//blockingQueue.put("d"); //队列没有位置了,会一直阻塞
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take()); //没有元素了,也会一直等待(阻塞)
}
示例3:等待,阻塞(等待超时)
public static void test4() throws InterruptedException {
//队列大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d",2, TimeUnit.SECONDS)); //等待超过2秒钟就退出
System.out.println("==============================");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll(2,TimeUnit.SECONDS));//等待超过2秒钟就退出
}
图片.png
SynchronousQueue 同步队列
没有容量,进去一个元素必须等待取出来后才能往里面放一个元素。(put、take)
package com.company.blockingqueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
/**
*同步队列
*/
public class TestSynchronizedQueue {
public static void main(String[] args) {
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()+" take "+synchronousQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+" take "+synchronousQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+" take "+synchronousQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T2").start();
}
}
结果:
T1 put 1
T2 take 1
T1 put 2
T2 take 2
T1 put 3
T2 take 3
网友评论