18. 线程通信-阻塞队列 比眉伴天荒 2024-04-17 21:45 22阅读 0赞 > java 多线程系列文章列表, 请查看目录: [《java 多线程学习笔记》][java] ## 1. 线程通信-阻塞队列 ## ### 1.1 阻塞API ### BlockingQueue 接口提供了两个阻塞方法: * void put(E e) throws InterruptedException: 像队列中添加元素, 如果队列已满, 则阻塞该线程. * E take() throws InterruptedException: 从队列中取出元素, 如果队列为空, 则阻塞该线程. ### 1.2 常见的阻塞队列 ### BlockingQueue 有以下几个实现类: * ArrayBlockingQueue: 基于数组实现的阻塞队列 * LinkedBlockingQueue: 基于连表实现的阻塞队列 * SynchronousQuue: 同步队列, 该队列的存取必须交替进行. 也就是说队列中最多只能有一个元素. * PriorityBlockingQuue: 并非标准的阻塞队列, 不是按先进先出方式存取, 而是按优先级排序存取. * DelayQueue: 特殊的阻塞队列, 要求所有元素必须都实现Delay 接口. ## 2. 阻塞队列示例 ## ### 2.1 使用阻塞队列改造Product ### 使用阻塞队列改造Product时, 无须再使用synchronized 或Lock 添加锁 public class Product { // 阻塞队列, 设置容量为1. 当容量为1时, 可替换为SynchronousQueue private BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1); public void sale(){ try { String poll = queue.take(); System.out.println(Thread.currentThread().getName() + "-获取商品:" + poll); } catch (InterruptedException e) { e.printStackTrace(); } } public void purchase() { try { String product = "product-" + new Random().nextInt(10); queue.put(product); System.out.println(Thread.currentThread().getName() + "-生产商品:" + product); } catch (InterruptedException e) { e.printStackTrace(); } } } ### 2.2 测试 ### public static void main(String[] args) { Product product = new Product(); // 启动三个线程消费 for (int i = 0; i < 3; i++) { new Thread("消费者" + i){ @Override public void run() { while (true) { product.sale(); } } }.start(); } // 启动一个线程生产 new Thread("生产者"){ @Override public void run() { while (true) { product.purchase(); ThreadUtil.sleep(10); } } }.start(); ThreadUtil.sleep(10000); } ### 2.3 输出 ### 消费者0-获取商品:product-4 生产者-生产商品:product-4 生产者-生产商品:product-8 消费者1-获取商品:product-8 生产者-生产商品:product-9 消费者2-获取商品:product-9 生产者-生产商品:product-6 消费者0-获取商品:product-6 生产者-生产商品:product-2 [java]: https://blog.csdn.net/zongf0504/article/details/100186060
还没有评论,来说两句吧...