Java多线程与并发库高级应用之阻塞队列BlockingQueue



JDK1.5提供了阻塞队列接口BlockingQueue,它是一个有界阻塞队列。BlockingQueue实现是线程安全的,可以安全地与多个生产者和多个使用者一起使用。

使用时用其实现类ArrayBlockingQueue,它一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。
这是一个典型的“有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致操作受阻塞;试图从空队列中提取元素将导致类似阻塞。

使用构造器ArrayBlockingQueue(int capacity)可以创建一个带有给定的(固定)容量和默认访问策略的ArrayBlockingQueue。
其put(E e)方法将指定的元素插入此队列的尾部,如果该队列已满,则等待可用的空间。
take()方法可以获取并移除此队列的头部,在元素变得可用之前一直等待。

见下面程序,程序中两条线程向队列中写入数据,一条线程读取数据。当队列已满时,写入线程阻塞;当队列空时,读取线程阻塞。
public class ArrayBlockingQueueDemo {

	public static void main(String[] args) {
		
		//阻塞队列,队列容量为3
		final BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(3);
		
		//两个线程向队列写入数据
		for(int i = 0; i < 2; i++){
			new Thread(){
				@Override
				public void run() {
					while(true){
						try{
							Thread.sleep((long)(Math.random()*1000));
							System.out.println(getName() + "-准备向队列写入数据");
							queue.put(1);
							System.out.println(getName() + "-已经向队列写入数据,队列一共有"
									+ queue.size() + "个数据");
						}catch(InterruptedException e){
							e.printStackTrace();
						}
					}
				}
			}.start();
		}
		
		//一个线程读取数据
		new Thread(){
			@Override
			public void run() {
				while(true){
					try{
						Thread.sleep(1000);
						System.out.println(getName() + "-准备从队列读取数据");
						queue.take();
						System.out.println(getName() + "-已经从队列读取数据,队列一共有"
								+ queue.size() + "个数据");
					}catch(InterruptedException e){
						e.printStackTrace();
					}
				}
			}
		}.start();
	}

}

运行程序


看到当队列已满时,写入线程阻塞知道有一个数据被取出后才能继续写入。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值