ArrayBlockingQueue
阻塞队列为空时:取元素的线程会被阻塞阻塞队列满时:
添加元素的线程会被阻塞消息中间件的底层原理之一就是阻塞队列为什么需要BlockQueue?
有了阻塞队列,程序员不需要关心线程什么时候需要wait,什么时候需要notify阻塞和取消阻塞都是自动的降低了程序复杂度ArrayBlockingQueue:
底层是数组的有界阻塞队列LinkedBlockingQueue: 底层是链表的有界阻塞队列,默认大小是2147483647PriorityBlockingQueue: 支持优先级排序的无界队列SynchronousQueue: 不存储元素的阻塞队列,只存储单个元素,消费一个元素,再生产一个元素。LinkedBlockingDeque: 由链表组成的双向阻塞队列
public class BlockQueueDemo {
/**
* ArrayBlockingQueue:
* add方法,当队列满时,再次添加元素会报IllegalStateException
* remove方法,当队列空时取元素会抛出异常
*/
@Test
public void test1(){
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);
System.out.println(queue.add(1));
System.out.println(queue.add(2));
System.out.println(queue.add(3));
System.out.println(queue.element());
System.out.println(queue.remove());
System.out.println(queue.remove(1));
System.out.println(queue.remove(2));
System.out.println(queue.remove(4));
System.out.println(queue.remove(3));
}
/**
* ArrayBlockingQueue:
* offer: 队列满时再插入不会报异常,而是返回false
* peek:探索队顶的元素是多少
* poll: 将元素拉出,没有元素时返回null
*/
@Test
public void test2(){
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);
System.out.println(queue.offer(1));
System.out.println(queue.offer(2));
System.out.println(queue.offer(3));
System.out.println(queue.offer(4));
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
}
/**
* ArrayBlockingQueue:
* put: 当队列满后,再次put的线程会被阻塞
* take: 当队列为空后,再次来取数的线程会被阻塞,直到队列里再有线程为止,
* 这就是队列代替wait/notify的场景
*
*/
@Test
public void test3() throws InterruptedException {
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);
queue.put(1);
queue.put(2);
queue.put(3);
System.out.println("----------");
System.out.println(queue.take());
System.out.println(queue.take());
System.out.println(queue.take());
System.out.println("----------");
System.out.println(queue.take());
}
/**
* ArrayBlockingQueue:
* offer(a, 1, seconds): 往队列里放元素,如果队列满了阻塞1秒,超时后就放弃
* poll(a, 1, seconds): 从队列里拿数据,如果队列为空,就阻塞,超时后放弃
*
*/
@Test
public void test4() throws InterruptedException {
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);
queue.offer(1, 1L, TimeUnit.SECONDS);
queue.offer(2, 1L, TimeUnit.SECONDS);
queue.offer(3, 1L, TimeUnit.SECONDS);
System.out.println("-----------");
queue.offer(4, 5L, TimeUnit.SECONDS);
}
}