阻塞队列BlockingQueue

22 篇文章 0 订阅
10 篇文章 0 订阅
阻塞队列BlockingQueue
  • 队列:一种数据结构,先进先出(排队取餐)
  • 阻塞队列:(交通拥堵)
  • 1)阻塞队列有没有好的一面(一种情况:海底捞火锅,消费者越多,越阻塞证明生意越好,欢迎阻塞)
  • 2)不得不阻塞,你如何管理?
什么是阻塞队列(BlockingQueue):
  • 当阻塞队列中元素为空的时候,从队列中获取元素的操作将被阻塞
  • 当阻塞队列中元素为满的时候,往队列中插入元素的操作将被阻塞
为什么用?有什么好处?
  • 在多线程领域,所谓阻塞:在某些情况下会挂起线程(即阻塞),达到条件满足时,线程被重新唤醒
  • synchronized的wait(挂起)和notify(唤醒),手动的
  • 而阻塞队列将会自动完成挂起和唤醒的操作,不用再关心什么时候需要阻塞,什么时候需要唤醒
阻塞队列接口种类分析?
  • ArrayBlockingQueue:(参照ArrayList)由数组结构组成的有界阻塞队列
  • LinkedBlockingQueue:(参照LinkedList)由链表结构组成的有界(但默认有界大小为Integer.MAX_VALUE(相当大,无意义))阻塞队列
  • SynchronousQueue:单个元素的队列(唯一定制版,生产一个,消费一个,有且仅有一个)
BlockingQueue的核心方法?
  • 4组API:
  • 抛出异常组:add(),remove(),element()
  • 返回布尔值组:offer(),poll(),peek()
  • 一直阻塞组:put(),take()
  • 阻塞超时组:offer(),poll()
    在这里插入图片描述

抛出异常组代码示例和解释:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueDemo {

   public static void main(String[] args){
   	
   	BlockingQueue<String> queue = new ArrayBlockingQueue<String>(3);//需要填默认初始值,确定有界多大
   	
   	System.out.println(queue.add("a"));//add添加元素
   	System.out.println(queue.add("b"));
   	System.out.println(queue.add("c"));
   	//System.out.println(queue.add("d"));//当元素对列满的时候会抛出异常( java.lang.IllegalStateException: Queue full)
   	
   	System.out.println("==================");
   	
   	System.out.println(queue.remove());//remove()移除,先进先出
   	System.out.println(queue.element());//element()检察当前队首元素值
   	System.out.println(queue.remove());
   	System.out.println(queue.remove());
   	//System.out.println(queue.element());//当队首元素空的时候,即元素队列空的时候会抛出异常(java.util.NoSuchElementException)
   	//System.out.println(queue.remove());//当元素队列空的时候会抛出异常(java.util.NoSuchElementException)
   }
   
}

返回布尔值组代码示例和解释:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueDemo {

	public static void main(String[] args){
		
		BlockingQueue<String> queue = new ArrayBlockingQueue<String>(3);//需要填默认初始值,确定有界多大
		
		System.out.println(queue.offer("a"));//offer添加元素
		System.out.println(queue.offer("b"));
		System.out.println(queue.offer("c"));
		System.out.println(queue.offer("d"));//当元素对列满的时候会返回false
		
		System.out.println("==================");
		
		System.out.println(queue.poll());//poll()移除,先进先出
		System.out.println(queue.peek());//peek()检察当前队首元素值
		System.out.println(queue.poll());
		System.out.println(queue.poll());
		System.out.println(queue.peek());//当队首元素空的时候,即元素队列空的时候会返回null
		System.out.println(queue.poll());//当元素队列空的时候会返回null
	}
	
}

一直阻塞组代码示例和解释:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueDemo {

   public static void main(String[] args){
   	
   	BlockingQueue<String> queue = new ArrayBlockingQueue<String>(3);//需要填默认初始值,确定有界多大
   	
   	try {
   		queue.put("a");//put添加元素
   		queue.put("b");
   		queue.put("c");
   		//queue.put("d");//当元素对列满的时候会使当前线程一直堵塞
   		
   		System.out.println("==================");
   		
   		System.out.println(queue.take());//take()移除,先进先出
   		System.out.println(queue.take());
   		System.out.println(queue.take());
   		//System.out.println(queue.take());//当元素队列空的时候会使当前线程一直堵塞
   	} catch (InterruptedException e) {
   		e.printStackTrace();
   	}
   	
   }
   
}

阻塞超时组代码示例和解释:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueDemo {

  public static void main(String[] args){
  	
  	BlockingQueue<String> queue = new ArrayBlockingQueue<String>(3);//需要填默认初始值,确定有界多大
  	
  	try {
  		System.out.println(queue.offer("a",2L,TimeUnit.SECONDS));//offer(添加的元素值,超时时间,时间工具类记录时分秒)添加元素
  		System.out.println(queue.offer("b",2L,TimeUnit.SECONDS));
  		System.out.println(queue.offer("c",2L,TimeUnit.SECONDS));
  		System.out.println(queue.offer("d",2L,TimeUnit.SECONDS));//当元素对列满的时候,会使当前线程堵塞,当堵塞超时后,返回false
  		
  		System.out.println("==================");
  		
  		System.out.println(queue.poll(2L,TimeUnit.SECONDS));//poll(超时时间,时间工具类记录时分秒)移除,先进先出
  		System.out.println(queue.poll(2L,TimeUnit.SECONDS));
  		System.out.println(queue.poll(2L,TimeUnit.SECONDS));
  		System.out.println(queue.poll(2L,TimeUnit.SECONDS));//当元素队列空的时候会使当前线程堵塞,当堵塞超时后,返回null
  	} catch (InterruptedException e) {
  		e.printStackTrace();
  	}
  	
  	
  }
  
}
阻塞队列之同步SynchronousQueue
  • 队列中只有一个元素,阻塞队列不为空时,添加元素会被一直阻塞,知道阻塞队列中元素被取出
  • 生产一个,消费一个

代码示例和解释:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
* 阻塞队列之同步SynchronousQueue
* 队列中只有一个元素,阻塞队列不为空时,添加元素会被一直阻塞,知道阻塞队列中元素被取出
* 生产一个,消费一个
*/
public class BlockingQueueDemo {

  	public static void main(String[] args){
  		
  		BlockingQueue<String> queue = new SynchronousQueue();//需要填默认初始值,确定有界多大
  		
  		//线程AAA
  		new Thread(()->{
  			
  			try {
  				System.out.println(Thread.currentThread().getName()+"\t put 1");
  				queue.put("1");
  				
  				//BBB线程取出队列中上一个元素后,队列中才能put新的元素
  				System.out.println(Thread.currentThread().getName()+"\t put 2");
  				queue.put("2");
  				
  				System.out.println(Thread.currentThread().getName()+"\t put 3");
  				queue.put("3");
  				
  			} catch (InterruptedException e) {
  				e.printStackTrace();
  			}
  			
  		},"AAA").start();
  		
  		//线程BBB
  		new Thread(()->{
  			try {
  				
  				TimeUnit.SECONDS.sleep(5);//等5秒钟后,BBB线程取出队列元素
  				System.out.println(Thread.currentThread().getName()+"\t"+queue.take());
  				
  				TimeUnit.SECONDS.sleep(5);
  				System.out.println(Thread.currentThread().getName()+"\t"+queue.take());
  				
  				TimeUnit.SECONDS.sleep(5);
  				System.out.println(Thread.currentThread().getName()+"\t"+queue.take());
  				
  			} catch (InterruptedException e) {
  				e.printStackTrace();
  			}
  			
  		},"BBB").start();
  		
  	}
  
  
}

打印结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值