Java技术1-线程池



参考资料:

http://developer.51cto.com/art/201202/314316.htm

 

所谓的线程池:

  1. 预创建一些默认数量的线程;

  2. 当有新任务到来时,直接调用线程池中的线程来完成任务;

  3. 创建线程的时间t1,销毁线程的时间t3,而线程真正做事的时间为t2

    那么只有在t2<t1+t3的情况下,使用线程池技术才是合理的;

 

类似于对象池,线程池要完成的功能也类似:

  1. 创建线程池;

  2. 销毁线程池;

  3. 添加任务:获取线程,返回线程;

 

此处要考虑的几个关键点:

  1. 对象池中我们采用vector数据结构来组织所有的对象,那么线程池中,我们采用什么数据结构来组织对象?

    后续的处理过程要求任务以特定的方式组织,如果考虑任务采用先到先执行的处理方式,那么就可以考虑将任务组织成队列;新到的任务到队列头,执行任务时只要队列头取一个任务即可。

 

  1. 线程的行为:有任务的时候,执行任务;而没任务的时候,线程应该处于阻塞状态;

    从线程的行为可以推得:

  1. 线程内部包含循环;b. 在没有任务时,线程应该处于睡眠状态;

 

  1. 要考虑线程与任务的绑定:

    简单地说:如何让线程来执行任务?如果所有的任务都实现一个统一的接口,这样的话,线程中就可以通过该接口来执行任务。此处我们让所有的任务实现runnable接口,相应的代码应该类似如下:

    run(){

      runnable r= null;

    while(isRunning){

        run = taskQueue().get();

        r.run();

    }

    }

     

    Class taskextends runnable{

            public void run(){

            }

    }

 

  1. 还需要注意同步的问题:taskqueue的操作需要保证串行特性,保证添加或者取出操作时的不相互干扰。所以在对taskqueue处理的时候需要增加对象锁,从而保证一致性。

     

     

    线程池的实现

     

    线程与任务主要的交互通过队列来实现:

    线程在没有任务的时候,就出于睡眠状态;一旦有任务了,线程就执行任务;对比对象池,需要为每个对象的状态进行设定;而线程池中不存在这样的问题;

    线程的状态:通过自己去查找taskqueue来改变。有任务那就进入执行任务状态;否则,线程就出于停顿等待过程;

     

1.对于线程池中的线程,命名为PooledThread.java,主要包含的操作:

  1. 访问任务队列,如果有新的任务就开始执行任务;

  2. 否则,当前的线程处于wait()状态;

  3. 主要的数据结构为:runnable接口变量,用来执行任务;

 

由于taskqueue是线程与任务之间的通道,所以taskqueue的设计是难点:

taskqueue的定义,涉及到runnable接口,本文中采用的是linkedList,整个的定义如下:

List<runnable>taskqueue = new LinkedList<runnable>();

 

那么要往其中增加对象的调用:

     Taskqueue.add(t); //ttask对象;

 

那么从taskqueue中取出一个对象可以使用:

     Taskqueue.remove(0);

 

如果要将整个的taskqueue中的任务都删除的话:

     可以使用如下的命令:taskqueue.clear();

 

2. 线程池中的创建线程池和销毁线程池方法都是需要的;

那么创建线程池时,createPool()需要根据线程池指定数量的工作线程数,创建相应数量的线程;并且将线程启动于开工状态;

 

而销毁线程时,也需要注意当前是否所有的线程都已经处于空闲状态;如果不是空闲的话,需要等待直到所有的线程都处于空闲(此处如何做到?;然后再将线程池销毁;所谓的空闲,也只要任务队列为空即可。

而销毁线程只要让工作线程退出循环状态即可。

 

  1. 与对象池对比,线程池中的线程是不需要回收的;但可以考虑动态地增加,如果当前线程池中的线程不够执行当前的所有任务,可以考虑动态扩展线程池中的线程;

 

  1. 任务对列中的增加与删除;对于任务队列中的任务删除,其实由工作线程调取任务队列中的任务就已经完成;

     

    往任务队列中增加任务,这需要有特定的接口,假设我们将其中你的接口定名为:execute;

    其中主要也是调用taskqueue.add()方法;该操作与taskqueue.remove()互斥,故使用taskqueue对象锁;

该思考的问题都都考虑到了,可以试着去实现下看看。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值