多线程 : 阻塞队列

BlockingQueue最终会有四种状况,抛出异常、返回特殊值、阻塞、超时,下表总结了这些方法:

 抛出异常特殊值阻塞超时
插入add(e)offer(e)put(e)offer(e, time, unit)
移除remove()poll()take()poll(time, unit)
检查element()peek()不可用不可用

       BlockingQueue是个接口,有如下实现类:

       1. ArrayBlockQueue:一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象必须明确大小,像数组一样。

       2. LinkedBlockQueue:一个可改变大小的阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象如果没有明确大小,默认值是Integer.MAX_VALUE。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。 

       3. PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。

       4. SynchronousQueue:同步队列。同步队列没有任何容量,每个插入必须等待另一个线程移除,反之亦然。

       下面使用ArrayBlockQueue来实现之前实现过的生产者消/费者模式,代码如下:

/** 定义一个盘子类,可以放鸡蛋和取鸡蛋 */
public class BigPlate {

	/** 装鸡蛋的盘子,大小为5 */
	private BlockingQueue<Object> eggs = new ArrayBlockingQueue<Object>(5);
	
	/** 放鸡蛋 */
	public void putEgg(Object egg) {
		try {
			eggs.put(egg);// 向盘子末尾放一个鸡蛋,如果盘子满了,当前线程阻塞
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		// 下面输出有时不准确,因为与put操作不是一个原子操作
		System.out.println("放入鸡蛋");
	}
	
	/** 取鸡蛋 */
	public Object getEgg() {
		Object egg = null;
		try {
			egg = eggs.take();// 从盘子开始取一个鸡蛋,如果盘子空了,当前线程阻塞
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		// 下面输出有时不准确,因为与take操作不是一个原子操作
		System.out.println("拿到鸡蛋");
		return egg;
	}
	
	/** 放鸡蛋线程 */
	static class AddThread extends Thread {
		private BigPlate plate;
		private Object egg = new Object();

		public AddThread(BigPlate plate) {
			this.plate = plate;
		}

		public void run() {
			plate.putEgg(egg);
		}
	}

	/** 取鸡蛋线程 */
	static class GetThread extends Thread {
		private BigPlate plate;

		public GetThread(BigPlate plate) {
			this.plate = plate;
		}

		public void run() {
			plate.getEgg();
		}
	}
	
	public static void main(String[] args) {
		BigPlate plate = new BigPlate();
		// 先启动10个放鸡蛋线程
		for(int i = 0; i < 10; i++) {
			new Thread(new AddThread(plate)).start();
		}
		// 再启动10个取鸡蛋线程
		for(int i = 0; i < 10; i++) {
			new Thread(new GetThread(plate)).start();
		}
	}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值