线程池(一)

    1. Java代码  收藏代码
      1. public ThreadPoolExecutor(int corePoolSize,  
      2. int maximumPoolSize,  
      3. long keepAliveTime,  
      4.                               TimeUnit unit,  
      5.                               BlockingQueue<Runnable> workQueue,  
      6.                               ThreadFactory threadFactory,  
      7.                               RejectedExecutionHandler handler) {  
      8. if (corePoolSize < 0 ||  
      9.             maximumPoolSize <= 0 ||  
      10.             maximumPoolSize < corePoolSize ||  
      11.             keepAliveTime < 0)  
      12. throw new IllegalArgumentException();  
      13. if (workQueue == null || threadFactory == null || handler == null)  
      14. throw new NullPointerException();  
      15. this.corePoolSize = corePoolSize;  
      16. this.maximumPoolSize = maximumPoolSize;  
      17. this.workQueue = workQueue;  
      18. this.keepAliveTime = unit.toNanos(keepAliveTime);  
      19. this.threadFactory = threadFactory;  
      20. this.handler = handler;  
      21.     }  
  1. 构造方法参数讲解
    参数名 作用
    corePoolSize 队列未满时,线程最大并发数;核心线程池大小如:80
    maximumPoolSize 队列满后线程能够到达的最大并发数;最大线程池大小如:100
    keepAliveTime

    线程池中超过corePoolSize数目的空闲线程最大存活时间;可以allowCoreThreadTimeOut(true)使得核心线程有效时间

    大于80剩余线程存活的时间

    TimeUnit keepAliveTime时间单位 大于80剩余线程存活的时间
    workQueue

    阻塞任务队列 :大于80之后进入该queue

    如corePoolSize=5 实际有10个线程,超出的5个将会存放到待队列里

    threadFactory 新建线程工厂
    RejectedExecutionHandler

    当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理;

    如maxmumPoolSize=5,workQueue的size=2,实际最大线程为10>7超出的3个线程将会提交给RejectedExecutionHandler

  2. 代码演示:
public class RejectedExecutionHandlerAction implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        executor.allowCoreThreadTimeOut(true);
        System.out.println("aaa"+ executor.getActiveCount());
    }
}
 public void test() throws InterruptedException {
        //队列不限定长度 无论实际有多少个线程都不会触发 RejectedExecutionHandler
        LinkedBlockingDeque linkedBlockingDeque = new LinkedBlockingDeque();
        RejectedExecutionHandlerAction action = new RejectedExecutionHandlerAction();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 5, TimeUnit.SECONDS, linkedBlockingDeque, action );
        for (int i = 0; i < 10; i++) {
            threadPoolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(" 线程名称:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入printA");
                }
            });
        }
        System.out.println(linkedBlockingDeque.size());
        Thread.sleep(20000);
        System.out.println(linkedBlockingDeque.size());
    }

运行结果:

指定队列长度,超出线程触发RejectedExecutionHandler

LinkedBlockingDeque linkedBlockingDeque = new LinkedBlockingDeque(2);

  1. corePoolSize,maximumPoolSize,workQueue之间关系。

    1. 当线程池中线程数小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。

    2. 当线程池中线程数达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行 。

    3. 当workQueue已满,且maximumPoolSize > corePoolSize时,新提交任务会创建新线程执行任务。

    4. 当workQueue已满,且提交任务数超过maximumPoolSize,任务由RejectedExecutionHandler处理。

    5. 当线程池中线程数超过corePoolSize,且超过这部分的空闲时间达到keepAliveTime时,回收这些线程。

    6. 当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize范围内的线程空闲时间达到keepAliveTime也将回收。

  2. 线程管理机制图示:

   

三、Executors提供的线程池配置方案 

1、构造一个固定线程数目的线程池,配置的corePoolSize与maximumPoolSize大小相同,同时使用了一个无界LinkedBlockingQueue存放阻塞任务,因此多余的任务将存在再阻塞队列,不会由RejectedExecutionHandler处理 

Java代码  收藏代码
  1. public static ExecutorService newFixedThreadPool(int nThreads) {  
  2. return new ThreadPoolExecutor(nThreads, nThreads,  
  3.                                       0L, TimeUnit.MILLISECONDS,  
  4. new LinkedBlockingQueue<Runnable>());  
  5.     }  


2、构造一个缓冲功能的线程池,配置corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60s,以及一个无容量的阻塞队列 SynchronousQueue,因此任务提交之后,将会创建新的线程执行;线程空闲超过60s将会销毁

Java代码  收藏代码
  1. public static ExecutorService newCachedThreadPool() {  
  2. return new ThreadPoolExecutor(0, Integer.MAX_VALUE,  
  3.                                       60L, TimeUnit.SECONDS,  
  4. new SynchronousQueue<Runnable>());  
  5.     }  


3、构造一个只支持一个线程的线程池,配置corePoolSize=maximumPoolSize=1,无界阻塞队列LinkedBlockingQueue;保证任务由一个线程串行执行

Java代码  收藏代码
  1. public static ExecutorService newSingleThreadExecutor() {  
  2. return new FinalizableDelegatedExecutorService  
  3.             (new ThreadPoolExecutor(1, 1,  
  4.                                     0L, TimeUnit.MILLISECONDS,  
  5. new LinkedBlockingQueue<Runnable>()));  
  6.     }  


4、构造有定时功能的线程池,配置corePoolSize,无界延迟阻塞队列DelayedWorkQueue;有意思的是:maximumPoolSize=Integer.MAX_VALUE,由于DelayedWorkQueue是无界队列,所以这个值是没有意义的

Java代码  收藏代码
    1. public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {  
    2. return new ScheduledThreadPoolExecutor(corePoolSize);  
    3.     }  
    4. public static ScheduledExecutorService newScheduledThreadPool(  
    5. int corePoolSize, ThreadFactory threadFactory) {  
    6. return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);  
    7.     }  
    8. public ScheduledThreadPoolExecutor(int corePoolSize,  
    9.                              ThreadFactory threadFactory) {  
    10. super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,  
    11. new DelayedWorkQueue(), threadFactory);  
    12.     }  
原文地址:https://www.cnblogs.com/fanBlog/p/8110106.html