1.阻塞队列
队列是一个数据结构,阻塞队列就是线程从一端添加数据,从一端拿取数据。当阻塞队列时空时,从队列中获取元素的操作将会被阻塞;当阻塞队列是满时,往队列里添加元素的操作将会被阻塞。
为什么需要阻塞队列?
线程之间的通信一般使用的是Object的wait()和notify(),阻塞队列不需要自己去关心什么时候线程被唤醒,什么时候线程阻塞,因为BlockingQueue自己会处理。
BlockingQueue接口

阻塞队列 |
描述 |
ArrayBlickingQueue |
由数组结构组成的有界阻塞队列 |
LinkedBlockingQueue |
由链表结构组成的有界阻塞队列(默认大小Integer.MAX_VALUE,21亿) |
PriorityBlockingQueue |
支持优先级排序的无界阻塞队列 |
DelayQueue |
使用优先级队列实现的延迟无界阻塞队列 |
SyncronousQueue |
不存储元素的阻塞队列,即单个元素的队列 |
LinkedTransferQueue |
由链表结构组成的无界阻塞队列 |
LinkedBlockingDeque |
由链表结构组成的双向阻塞队列 |
API使用
方法类型 |
抛异常 |
特殊值 |
阻塞 |
超时 |
插入 |
add(e) |
offer(e) |
put(e) |
offer(e,time,unit) |
移除 |
remove() |
poll() |
take() |
poll(time,unit) |
检查 |
element() |
peek() |
不可用 |
不可用 |
1.抛异常add和remove
1.异常:当阻塞队列满时,往队列中add元素会有IllegalStateException:Queue full;当阻塞队列为空时,再往队列remove元素就会有NoSuchElementException
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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("b"));
System.out.println(blockingQueue.element());
System.out.println(blockingQueue.remove()); System.out.println(blockingQueue.remove()); System.out.println(blockingQueue.remove());
}
|
2.特殊值offer和poll
2.特殊值:插入方法,成功true失败返回false;移除方法成功返回队列的元素,失败返回null
1 2 3 4 5 6 7 8 9 10 11 12
| 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("b")); System.out.println(blockingQueue.offer("d")); System.out.println(blockingQueue.element()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); }
|
3.使用put和take,会阻塞
3.一致阻塞:当阻塞队列满时,生产者继续put元素时,队列会阻塞生产者线程知道put数据成功或者中断退出;当阻塞队列为空时,消费者线程take元素,队列会一致阻塞消费者线程直到队列可用
1 2 3 4 5 6 7 8 9 10 11 12
| public static void main(String[] args) throws InterruptedException { BlockingQueue<String> blockingQueue = new ArrayBlockingQueue(3); blockingQueue.put("a"); blockingQueue.put("b"); blockingQueue.put("b");
System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); }
|
4.超时退出使用加参数的offer和poll
4.当阻塞队列满时,队列会阻塞生产社线程一定时间,超时后生产者线程会退出
1 2 3 4 5 6 7 8 9 10 11 12
| public static void main(String[] args) throws InterruptedException { BlockingQueue<String> blockingQueue = new ArrayBlockingQueue(3); blockingQueue.offer("a",2L, TimeUnit.SECONDS); blockingQueue.offer("b",2L, TimeUnit.SECONDS); blockingQueue.offer("c",2L, TimeUnit.SECONDS); blockingQueue.offer("d",2L, TimeUnit.SECONDS);
System.out.println(blockingQueue.poll(2L, TimeUnit.SECONDS)); System.out.println(blockingQueue.poll(2L, TimeUnit.SECONDS)); System.out.println(blockingQueue.poll(2L, TimeUnit.SECONDS)); System.out.println(blockingQueue.poll(2L, TimeUnit.SECONDS)); }
|
同步阻塞队列SynchronousQueue
SynchronousQueue没有容量,与其他的BlockingQueue不同,SynchronousQueue是一个不存储元素的BlockingQueue,每一个out操作必须等待一个take操作,都则不能继续添加元素。