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

来源:互联网 发布:mac 链接无线键盘 编辑:程序博客网 时间:2024/06/05 04:41

我们都知道线程池有很多好处:

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

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

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

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


一。阻塞队列(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)

这两个类型的返回意义如下:

  1. Throws Exception: 
    如果这个操作不能立即执行,那么抛出异常
  2. 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: 这四各类型的返回意义如下:

  1. 如果这个操作不能立即执行,那么抛出异常
  2. Special Value: 
    如果这个操作不能立即执行,那么相应返回(true/false)
  3. Blocks: 
    如果这个操作不能立即执行,那么操作阻塞等待,直到操作可以执行。
  4. 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(){@Overridepublic 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(){@Overridepublic 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概念,在以后线程池的实现中有很大用处


0 0
原创粉丝点击