您的位置:首页 > 产品设计 > UI/UE

java线程池学习(一) —— BlockingQueue

2015-01-08 17:02 176 查看
我们都知道线程池有很多好处:

通过重复利用已经创建好的线程,可以减少创建线程时的资源消耗。

如果不限制线程的数量,不仅会大量消耗系统内存,还会照成系统的不稳定。

使用线程池,可以控制线程的数量,还可以对所有线程进行统一的管理,好处不言而喻。

那么在详细了解线程池之前。我们需要先复习一些概念

一。阻塞队列(BlockingQueue)

先看一下阻塞队列的代码关系:interface BlockingQueue<E> extends Queue<E>

我们发现这是一个继承了Queue的接口。BlockingQueue有什么特性呢?我们做以下功课:

二。我们先看看最原始接口Queue Interface的方法:

java源码注释已经帮我们分类好了:

最原始的Queue Interface有两种类型的插入,删除,和获取元素方法,归类如下:

Throws ExceptionSpecial Value
插入类add(o)offer(o)
删除类remove(o)poll(o)
获取类element(o)peek(o)
这两个类型的返回意义如下:

Throws Exception:

如果这个操作不能立即执行,那么抛出异常
Special Value:

如果这个操作不能立即执行,那么相应返回(true/false)

三。我们再看看BlockingQueue Interface的方法

java 源码注释里面已经很清楚帮我们分类好了

BlockingQueue有四种类型的插入,删除,和获取元素方法,归类如下:

Throws ExceptionSpecial ValueBlocksTimes Out
插入类add(o)offer(o)put(o)offer(o, timeout, timeunit)
删除类remove(o)poll(o)take(o)poll(timeout, timeunit)
获取类element(o)peek(o)
Throws Exception: 这四各类型的返回意义如下:

如果这个操作不能立即执行,那么抛出异常
Special Value:

如果这个操作不能立即执行,那么相应返回(true/false)
Blocks:

如果这个操作不能立即执行,那么操作阻塞等待,直到操作可以执行。

Times Out:

如果这个操作不能立即执行,那么操作阻塞等待,直到操作可以执行,但是有限定时间,如果超过时间还没有完成,就会返回错误信息(false)

我们可以很明显的看到BlockingQueue加入了阻塞等待的操作,可以理解成如果队列满了,插入任务就在门口等着,不抛出错误信息,直到有元素从队列中取出,队列有空位了,再进行插入操作,相应的你还可以加入等待超时机制,如果过时了,就不等了。

我们写个例子看看:

package test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueTest {

public static void main(String[] args) {
//初始化队列长度只有3的队列
final BlockingQueue<String> blockingque = new ArrayBlockingQueue<String>(3);
Thread Putter = new Thread(new Runnable(){
@Override
public void run() {
for(int i=1;i<10;i++){
try {
blockingque.put("货物"+i);
System.out.println("成功往队列中放入货物"+i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

});
Putter.start();
Thread taker = new Thread(new Runnable(){
@Override
public void run() {
while(true){
try {
//取得时间延长,模拟取得时间远大于放入时间
Thread.sleep(3000);
String cargo = blockingque.take();
System.out.println("取出货物: "+cargo);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

});
taker.start();

}

}


输出结果为:

成功往队列中放入货物1
成功往队列中放入货物2
成功往队列中放入货物3
取出货物: 货物1
成功往队列中放入货物4
取出货物: 货物2
成功往队列中放入货物5
取出货物: 货物3
成功往队列中放入货物6
取出货物: 货物4
成功往队列中放入货物7
取出货物: 货物5
成功往队列中放入货物8
取出货物: 货物6
成功往队列中放入货物9
取出货物: 货物7
取出货物: 货物8
取出货物: 货物9


我们可以看到队列长度为3,队列放满3个后,put()方法就处于blocking的状态等待队列有位子

过了3秒后,getter开始从队列中取货物,一有空位,put()方法就得以继续执行。

二。interface BlockingQueue的实现

由于BlockingQueue只是一个接口,需要类实现,java已经有了以下的几个类实现BlockingQueue(java 6)

ArrayBlockingQueue
DelayQueue
LinkedBlockingQueue
PriorityBlockingQueue
SynchronousQueue

关于这几个实现的之间差别以后有时间在深入探索。

最主要的,还是BlockingQue的Blocking概念,在以后线程池的实现中有很大用处
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: