阻塞队列BlockingQueue
一、什么是阻塞队列从名字可以看出阻塞队列是队列的一种,是一种FIFO(先进先出)的数据结构,与普通队列不同的是,它支持阻塞添加和阻塞删除阻塞添加:当队列已满时,往队列中添加元素会阻塞等待阻塞删除:当队列为空时,往队列中删除或获取元素将被阻塞二、阻塞队列的四组API方式抛出异常不会抛出异常,有返回值阻塞等待超时等待添加add()offer()put()offer(e,timeout,Tim...
·
一、什么是阻塞队列
从名字可以看出阻塞队列是队列的一种,是一种FIFO(先进先出)的数据结构,与普通队列不同的是,它支持阻塞添加和阻塞删除
阻塞添加:当队列已满时,往队列中添加元素会阻塞等待
阻塞删除:当队列为空时,往队列中删除或获取元素将被阻塞
二、阻塞队列的四组API
方式 | 抛出异常 | 不会抛出异常,有返回值 | 阻塞等待 | 超时等待 |
添加 | add() | offer() | put() | offer(e,timeout,TimeUnit) |
移除 | remove() | poll() | take() | poll(timeout,TimeUnit) |
获取队首元素 | element() | peek() | - | - |
1.抛出异常
public static void test1(){
//括号里填的是队列大小,看源码
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
for (int i = 0; i < 3; i++) {
System.out.println(blockingQueue.add(String.valueOf(i)));
}
//获取队首元素
System.out.println(blockingQueue.element());
//队列已满,再向队列中添加元素会抛异常 : Queue full --> 队列已满
//blockingQueue.add("hhh");
System.out.println("===================");
//弹出队列中元素
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
//队列已空,再向队列中取元素会抛出异常 NoSuchElementException --> 没有元素
//blockingQueue.remove();
}
2.不抛出异常,有返回值
public static void test2(){
//同样括号中填队列大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
for (int i = 0; i < 3; i++) {
System.out.println(blockingQueue.offer(String.valueOf(i)));
}
//获取队首元素
System.out.println(blockingQueue.peek());
//此时队列已满,再向队列中添加元素会返回false
System.out.println(blockingQueue.offer("hhh"));
System.out.println("===========");
//弹出队列中元素
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
//此时队列为空,再弹出元素不会抛出异常,返回null
System.out.println(blockingQueue.poll());
}
3.阻塞等待
public static void test3() throws InterruptedException {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
for (int i = 0; i < 3; i++) {
blockingQueue.put(String.valueOf(i));
}
//队列没有位置了,会一直阻塞
//blockingQueue.put("hhhh");
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
//队列为空,会一直阻塞
//System.out.println(blockingQueue.take());
}
4.超时等待
public static void test4() throws InterruptedException {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(3);
for (int i = 0; i < 3; i++) {
System.out.println(blockingQueue.offer(String.valueOf(i)));
}
//队列已满,设置等待时间,如果等待时间到了元素还没有位置插入,就会超时退出
//blockingQueue.offer("hhh",2, TimeUnit.SECONDS);
System.out.println("============");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
//队列已空,设置等待时间,如果等待时间到了队列中还没有元素,就会超时退出并返回null
System.out.println(blockingQueue.poll(2,TimeUnit.SECONDS));
}
三、同步队列 SynchronousQueue
和其他BlockingQueue不同
同步队列不存储元素
同队列 put 一个元素 必须等待该元素take出队列后才能put下一个元素
public class SynchronousQueueTest {
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()+" get "+synchronousQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+" get "+synchronousQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+" get "+synchronousQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T2").start();
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)