java自带的线程池ThreadPoolExecutor

来源:互联网 发布:用友u8 数据库 编辑:程序博客网 时间:2024/04/27 22:56

      线程池可以减少每个任务调用的开销,也就是减少单个任务的等待时间.当使用单线程时,任务需要进行排队,在线程池中,每个任务都有自己的线程,不再排队,实现多任务同时处理.


     java.util.concurrent.ThreadPoolExecutor的常用构造方法如下:
     ThreadPoolExecutor(int        corePoolSize, 
                                      int        maximumPoolSize,
                                      long     keepAliveTime,
                                      TimeUnit unit,
                                      BlockingQueue<Runnable> workQueue
                                      RejectedExecutionHandler handler)
     corePoolSize:         线程池维护线程的最少线程数,也是核心线程数,包括空闲线程
     maximumPoolSize: 线程池维护线程的最大线程数
     keepAliveTime:       线程池维护线程所允许的空闲时间
     unit:                       程池维护线程所允许的空闲时间的单位
     workQueue:           线程池所使用的缓冲队列
     handler:                 线程池对拒绝任务的处理策略


     任务通过execute(Runnable)方法添加到线程池,一个任务就是一个Runnable对象,任务的执行就是Runnable对象的run()方法.
当一个任务将被添加到线程池中时:
     如果当前线程数小于corePoolSize,即使有空闲线程,也会创建新的线程来处理新增任务;
     如果当前线程数等于corePoolSize,如果缓冲队列未满,该任务被放入缓冲队列;
     如果当前线程数大于corePoolSize,且冲队列已满,如果当前线程数小于maximumPoolSize, 就创建新的线程来处理新增任务;
     如果当前线程数等于maximumPoolSize,且冲队列已满,将会使用handler所指定的策略来处理任务.
    

     线程池处理任务的顺序是:
     核心线程corePoolSize,   缓冲队列workQueue,  最大线程maximumPoolSize
     当前线程数大于corePoolSize,线程池中的空闲线程在超过keepAliveTime, 会自动终止.线程池通过keepAliveTime来动态维护线程数.
     unit的可选参数是java.util.concurrent.TimeUnit类中的
     MICROSECONDS MILLISECONDS NANOSECONDS SECONDS
     workQueue的参数有:
     java.util.concurrent.ArrayBlockingQueue,该队列的长度有限制
     java.util.concurrent.LinkedBlockingQueue,该队列的长度没有限制
     建议使用ArrayBlockingQueue


    handler的可选参数有:
    ThreadPoolExecutor.AbortPolicy                                   抛出 RejectedExecutionException.
   static class ThreadPoolExecutor.CallerRunsPolicy          重试添加当前任务,会重复调用execute();
   static class ThreadPoolExecutor.DiscardOldestPolicy     放弃最旧的任务,然后重试 execute()方法;
   static class ThreadPoolExecutor.DiscardPolicy               放弃当前任务.

示例代码:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class TestExecutor {

 public static void main(String[] args) {

  ThreadPoolExecutor executor = new ThreadPoolExecutor(
    2, 5, 300, TimeUnit.MILLISECONDS,
    new ArrayBlockingQueue<Runnable>(3),
    new ThreadPoolExecutor.CallerRunsPolicy()
  );
  for (int i=1; i<15; i++){
   executor.execute(new Task(i));
  }
  executor.shutdown();
 }
}

class Task implements Runnable{
 
 public Task(int num){
  this.num = num;
 }
 
 public void run() {
  System.out.println("任务名称="+"taskName"+num);
  try {
   Thread.sleep(500);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 private int num;
}


ThreadPoolExecutor除了execute()方法外,还有afterExecute(),beforeExecute(),
另外,可以对ThreadPoolExecutor重写受保护的方法进行扩展.

原创粉丝点击