博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java线程(7)——阻塞队列BlockingQueue
阅读量:4877 次
发布时间:2019-06-11

本文共 2727 字,大约阅读时间需要 9 分钟。

回顾:

阻塞队列,英文名叫BlockingQueue。首先他是一种队列,联系之前中介绍的Queue与Collection,我们就很容易开始今天的阻塞队列的学习了。来看一下他们的接口定义:

Queue:

(方法很简单,就不一一注释解释其作用了。)

public interface Queue
extends Collection
{ boolean add(E e); boolean offer(E e); E remove(); E poll(); E element(); E peek();}
BlockingQueue:

      因为是继承自Queue,方法基本类似,就不再写了。主要方法有三个:add,remove,element(用于检查)。

      那到底什么是阻塞队列呢?联系前面的例子,在篮子中没有馒头时,生成者要放入馒头消费者才能食用;在篮子里装满馒头时,生产者就不能继续生产了,要等人去吃。阻塞队列就是生产者存放馒头的容器,消费者从中取出元素,也就是那个篮子。

public interface BlockingQueue
extends Queue
{...... }
      BlockingQueue的实现类有很多,这里介绍一个很简单的ArrayBlockingQueue。他是一个数据结构组成的阻塞队列,按照FIFO先进先出的方式排序。

继续来看他的定义,下面只列举了常用的两个方法:

public class ArrayBlockingQueue
extends AbstractQueue
implements BlockingQueue
, java.io.Serializable { //放入元素 public void put(E e) throws InterruptedException { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == items.length) notFull.await(); enqueue(e); } finally { lock.unlock(); } } //取元素 public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == 0) notEmpty.await(); return dequeue(); } finally { lock.unlock(); } } }

来个例子:

//Capacity为3的阻塞队列		final BlockingQueue queue = new  ArrayBlockingQueue(3);		for (int i = 0; i < 2; i++) {			//1、放馒头线程			new Thread() {				@Override				public void run() {					while (true) {						try {							Thread.sleep((long) (Math.random() * 10000));							System.out.println(Thread.currentThread().getName()									+ "准备放馒头!");							//每次放入一个馒头							queue.put(1);							System.out.println(Thread.currentThread().getName()									+ "已经放了馒头," + "队列目前有" + queue.size()									+ "个馒头");						} catch (InterruptedException e) {							e.printStackTrace();						}					}				}			}.start();		}		//2、取馒头线程		new Thread() {			@Override			public void run() {				while (true) {					try {						Thread.sleep((long) (Math.random() * 10000));						System.out.println(Thread.currentThread().getName()								+ "准备取馒头!");						//拿走一个						queue.take();						System.out.println(Thread.currentThread().getName()								+ "已经取走馒头," + "队列目前有" + queue.size() + "个馒头");					} catch (InterruptedException e) {						e.printStackTrace();					}				}			}		}.start();	}

部分执行结果:

对比:

       和之前手动实现生产者消费者的例子相比,这次的实现就简单多了。不再需要去管篮子里的“取”和“放”的操作,不用关心线程的同步互斥问题,不用关心篮子是空了还是满了。只需要简单的调用put或take方法即可,把复杂的阻塞问题教给BlockingQueue去处理,但是原理还是一样的。

转载于:https://www.cnblogs.com/saixing/p/6730215.html

你可能感兴趣的文章
js兼容各个浏览器的复制功能
查看>>
数字反转
查看>>
Unique Binary Search Trees II
查看>>
素数筛选-hdu2710
查看>>
WebService 生成客户端
查看>>
VxWorks嵌入式系统几种常用的延时方法 分类: vxWorks ...
查看>>
Swagger使用总结
查看>>
powershell 删除7天前的文件
查看>>
”十六“进制查看器
查看>>
阿里云人脸识别接口调用。
查看>>
程序员如何选择学习新知识
查看>>
STM32小知识笔记
查看>>
使用C#执行PowerShell命令
查看>>
爬虫之scrapy--基本操作
查看>>
Android开发之游戏中的数学、物理、AI
查看>>
SM13 中 V1 和 V2 的区别
查看>>
谈谈LoadRunner中Pacing的设置
查看>>
使用EntityFramework6完成增删查改和事务
查看>>
Linux小技巧
查看>>
ASP.NET 文本框失去焦点事件验证用户是否已经存在
查看>>