BlockingQueue
BlockingQueue的作用和消息中间件一样,他可以削峰,限流,解耦
BlockingQueue最贴合的应用场景就是生产者消费者模式。
BlockingQueue是一个线程通讯的工具。
BlockingQueue的线程安全的,在任意时刻,无论并发有多高,在jvm上同意时间只有一个线程能够对队列进行入队或出队操作。
blockingQueue被应用到的地方有:
线程池,eruca,nacos,netty。
常用的BlockingQueue咋AQS 中的继承关系图:
入队方法:
boolean add(E e); 强制将元素e加入队列,如果队列已满抛出异常java.lang.IllegalStateException: Queue full
boolean offer(E e); 将元素e加入队列,如果成功返回true否则false
boolean offer(E e, long timeout, TimeUnit unit) 将元素e加入队列,如果成功返回true,如果等待一段时间后还失败,返回false
void put(E e) 将元素e加入队列,如果队列已满,阻塞等待直到队列有空就位置
出队方法:
E remove(); 强制将队列第一个元素提前出来,如果队列里面没之,抛出错误 java.util.NoSuchElementException
boolean remove(Object o); 提取元素o,如果没有元素返回false,如果存在多个,提取第一个。o.equals查找元素
E poll() 提取第一个元素,如果存在返回元素,否则返回null
E poll(long timeout, TimeUnit unit) 提取第一个元素,如果存在返回元素,如果等待一段时间后还说失败,返回null
E take() 提取第一个元素,如果队列为空,阻塞等待到有元素为止
示例:
add方法:
boolean add(E e); 强制将元素e加入队列,如果队列已满抛出异常java.lang.IllegalStateException: Queue full
@Test
public void arrayBlockingQueueAddFull(){
BlockingQueue arrayQueue = new ArrayBlockingQueue(5,true);
for (int i = 0; i <6 ; i++) {
arrayQueue.add(1);
System.out.println ( "add got success:"+ i );
}
}
执行结果:
offer方法:
boolean offer(E e); 将元素e加入队列,如果成功返回true否则false
boolean offer(E e, long timeout, TimeUnit unit) 将元素e加入队列,如果成功返回true,如果等待一段时间后还失败,返回false
@Test
public void arrayBlockingQueueOfferFull() throws InterruptedException {
BlockingQueue arrayQueue = new ArrayBlockingQueue(5,true);
for (int i = 0; i <6 ; i++) {
System.out.println ( "result: " + arrayQueue.offer(i));
}
System.out.println ( "result: " + arrayQueue.offer(1,2,TimeUnit.SECONDS));
}
执行结果:
put方法:
void put(E e) 将元素e加入队列,如果队列已满,阻塞等待直到队列有空就位置
@Test
public void arrayBlockingQueueTakeFull() throws InterruptedException {
BlockingQueue arrayQueue = new ArrayBlockingQueue(5,true);
for (int i = 0; i <6 ; i++) {
arrayQueue.put(i);
System.out.println ( "put got success:"+ i );
}
}
Remove 方法1:
E remove(); ,强制将队列第一个元素提前出来,如果队列里面没之,抛出错误 java.util.NoSuchElementException
@Test
public void arrayBlockingQueueRemoveFull() throws InterruptedException {
BlockingQueue arrayQueue = new ArrayBlockingQueue(5,true);
for (int i = 0; i <5 ; i++) {
arrayQueue.put(i);
}
for (int i = 0; i <6 ; i++) {
System.out.println ( "remove got success:"+ arrayQueue.remove() );
}
}
执行结果:
poll/remove方法:
boolean remove(Object o);提取元素o,如果没有元素返回false,如果存在多个,提取第一个。o.equals查找元素
E poll() 提取第一个元素,如果存在返回元素,否则返回null
@Test
public void arrayBlockingQueueRemoveEFull() throws InterruptedException {
BlockingQueue arrayQueue = new ArrayBlockingQueue(5,true);
arrayQueue.put("a");
arrayQueue.put("b");
arrayQueue.put("c");
arrayQueue.put("b");
System.out.println ( "put got success:"+ arrayQueue.remove("b") );
System.out.println ( "put got success:"+ arrayQueue.remove("z") );
System.out.println ( "put got success:"+ arrayQueue.poll(2, TimeUnit.SECONDS ));
while (!arrayQueue.isEmpty()){
System.out.println ( "put got success:"+ arrayQueue.remove() );
}
System.out.println ( "put got success:"+ arrayQueue.poll(2, TimeUnit.SECONDS ));
System.out.println ( "put got success:"+ arrayQueue.poll());
}
执行结果:
take方法:
E take() ,提取第一个元素,如果队列为空,阻塞等待到有元素为止
@Test
public void arrayBlockingQueueTake() throws InterruptedException {
BlockingQueue arrayQueue = new ArrayBlockingQueue(5,true);
arrayQueue.put("a");
System.out.println ( "take got success:"+ arrayQueue.take() );
System.out.println ( "put got success:"+ arrayQueue.take() );
}