傻大方


首页 > 潮·科技 > >

阻塞队列(1)java 7 种BlockingQueue介绍



按关键词阅读:

阻塞队列(1)java 7 种BlockingQueue介绍文章插图
BlockingQueue+概览
一些值得思考的问题

  • 为什么要有阻塞队列?
  • 什么是阻塞队列
  • 优缺点
  • 适用场景
  • 实现思想+源码
  • 个人启发
阻塞队列什么是阻塞队列?
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列 。 这两个附加的操作是:在队列为空时 , 获取元素的线程会等待队列变为非空 。 当队列满时 , 存储元素的线程会等待队列可用 。 阻塞队列常用于生产者和消费者的场景 , 生产者是往队列里添加元素的线程 , 消费者是从队列里拿元素的线程 。 阻塞队列就是生产者存放元素的容器 , 而消费者也只从容器里拿元素 。
阻塞队列提供了四种处理方法:
阻塞队列(1)java 7 种BlockingQueue介绍文章插图
抛出异常:是指当阻塞队列满时候 , 再往队列里插入元素 , 会抛出IllegalStateException(“Queue full”)异常 。 当队列为空时 , 从队列里获取元素时会抛出NoSuchElementException异常。
返回特殊值:插入方法会返回是否成功 , 成功则返回true 。 移除方法 , 则是从队列里拿出一个元素 , 如果没有则返回null
一直阻塞:当阻塞队列满时 , 如果生产者线程往队列里put元素 , 队列会一直阻塞生产者线程 , 直到拿到数据 , 或者响应中断退出 。 当队列空时 , 消费者线程试图从队列里take元素 , 队列也会阻塞消费者线程 , 直到队列可用 。
超时退出:当阻塞队列满时 , 队列会阻塞生产者线程一段时间 , 如果超过一定的时间 , 生产者线程就会退出 。
阻塞队列(1)java 7 种BlockingQueue介绍文章插图
阻塞队列
入门例子演示如何简单实用 BlockingQueue 。
测试类import java.util.concurrent.BlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingQueue; public class BlockingQueueTest {public static void main(String[] args) throws InterruptedException {// 声明一个容量为10的缓存队列BlockingQueue queue = new LinkedBlockingQueue(10);//new了三个生产者和一个消费者Producer producer1 = new Producer(queue);Producer producer2 = new Producer(queue);Producer producer3 = new Producer(queue);Consumer consumer = new Consumer(queue);// 借助ExecutorsExecutorService service = Executors.newCachedThreadPool();// 启动线程service.execute(producer1);service.execute(producer2);service.execute(producer3);service.execute(consumer);// 执行10sThread.sleep(10 * 1000);producer1.stop();producer2.stop();producer3.stop();Thread.sleep(2000);// 退出Executorservice.shutdown();}}生产者线程import java.util.Random;import java.util.concurrent.BlockingQueue;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;/** * 生产者线程 ** @author jackyuj */public class Producer implements Runnable {private volatile booleanisRunning = true;//是否在运行标志private BlockingQueue queue;//阻塞队列private static AtomicInteger count = new AtomicInteger();//自动更新的值private static final int DEFAULT_RANGE_FOR_SLEEP = 1000;//构造函数public Producer(BlockingQueue queue) {this.queue = queue;}public void run() {String data = http://kandian.youth.cn/index/null;Random r = new Random();System.out.println("启动生产者线程!");try {while (isRunning) {System.out.println("正在生产数据...");Thread.sleep(r.nextInt(DEFAULT_RANGE_FOR_SLEEP));//取0~DEFAULT_RANGE_FOR_SLEEP值的一个随机数data = "http://kandian.youth.cn/index/data:" + count.incrementAndGet();//以原子方式将count当前值加1System.out.println("将数据:" + data + "放入队列...");if (!queue.offer(data, 2, TimeUnit.SECONDS)) {//设定的等待时间为2s , 如果超过2s还没加进去返回trueSystem.out.println("放入数据失败:" + data);}}} catch (InterruptedException e) {e.printStackTrace();Thread.currentThread().interrupt();} finally {System.out.println("退出生产者线程!");}}public void stop() {isRunning = false;}}消费者代码import java.util.Random;import java.util.concurrent.BlockingQueue;import java.util.concurrent.TimeUnit;/** * 消费者线程 ** @author jackyuj */public class Consumer implements Runnable {private BlockingQueue queue;private static final int DEFAULT_RANGE_FOR_SLEEP = 1000;//构造函数public Consumer(BlockingQueue queue) {this.queue = queue;}public void run() {System.out.println("启动消费者线程!");Random r = new Random();boolean isRunning = true;try {while (isRunning) {System.out.println("正从队列获取数据...");String data = http://kandian.youth.cn/index/queue.poll(2, TimeUnit.SECONDS);//有数据时直接从队列的队首取走 , 无数据时阻塞 , 在2s内有数据 , 取走 , 超过2s还没数据 , 返回失败if (null != data) {System.out.println("拿到数据:" + data);System.out.println("正在消费数据:" + data);Thread.sleep(r.nextInt(DEFAULT_RANGE_FOR_SLEEP));} else {// 超过2s还没数据 , 认为所有生产线程都已经退出 , 自动退出消费线程 。isRunning = false;}}} catch (InterruptedException e) {e.printStackTrace();Thread.currentThread().interrupt();} finally {System.out.println("退出消费者线程!");}}}


稿源:(未知)

【傻大方】网址:http://www.shadafang.com/c/111J30XH020.html

标题:阻塞队列(1)java 7 种BlockingQueue介绍


上一篇:屏幕上|男子花1000元买报废苹果X, 本以为亏大了, 结果却很意外

下一篇:ARGON18|新款ARGON18全能向公路车上市 更硬更持久