java 线程池

概述

  1. 减小了建立和销毁线程的次数,每一个工做线程均可以被重复利用,可执行多个任务
  2. 能够根据系统的承受能力,调整线程池中工做线线程的数目,防止由于由于消耗过多的内存,而把服务器累趴下(每一个线程须要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)
  3. 线程池使得线程能够复用,就是执行完一个任务,并不被销毁,而是能够继续执行其余的任务,减小建立和销毁线程的次数。

java 中提供了3种实现

  1. ThreadPoolExecutor:标准线程池
  2. ScheduledThreadPoolExecutor:支持延迟任务的线程池
  3. ForkJoinPool:相似于ThreadPoolExecutor,可是使用work-stealing模式,其会为线程池中的每一个线程建立一个队列,从而用work-stealing(任务窃取)算法使得线程能够从其它线程队列里窃取任务来执行。既若是本身的任务处理完成了,则能够去忙碌的工做线程那里窃取任务执行。

1.ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler){
 ...... 
}
  • corePoolSize:核心线程池大小,线程池维护的线程最少线程。
  • maximumPoolSize:线程池最大大小。
  • keepAliveTime:线程池中线程的最大空闲时间,若是线程池中的线程个数大于corePoolSize,而且线程空闲时间超过该时间的线程会被回收。
  • unit: 线程池维护线程所容许的空闲时间的单位、可选参数值为:TimeUnit中的几个静态属性:NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。
  • workQueue: 线程池中存放工做任务的队列。经常使用的是:java.util.concurrent.ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue
  • threadFactory: 线程工厂,提供建立新线程的功能。ThreadFactory是一个接口,只有一个方法,经过线程工厂能够对线程的一些属性进行定制。
  • handler:线程池中的数量大于maximumPoolSize,对拒绝任务的处理策略,默认值ThreadPoolExecutor.AbortPolicy()。

Executors 提供了3个工厂方法建立 ThreadPoolExecutor

  1. newFixedThreadPool 建立一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
}
  1. newCachedThreadPool建立一个可缓存线程池,若是线程池长度超过处理须要,可灵活回收空闲线程,若无可回收,则新建线程。
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
}
  1. newSingleThreadExecutor 建立一个单线程化的线程池,它只会用惟一的工做线程来执行任务,保证全部任务按照指定顺序(FIFO, LIFO, 优先级)执行
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
}

2. ScheduledThreadPoolExecutor

咱们经过查看ScheduledThreadPoolExecutor的源代码,能够发现ScheduledThreadPoolExecutor继承了ThreadPoolExecutor。java

public ScheduledThreadPoolExecutor(int corePoolSize,
                                   ThreadFactory threadFactory,
                                   RejectedExecutionHandler handler) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
          new DelayedWorkQueue(), threadFactory, handler);
}

从构造中发现ScheduledThreadPoolExecutor线程池实际上是调用了ThreadPoolExecutor构造进行实现的,只是ThreadPoolExecutor使用的工做队列是java.util.concurrent.ScheduledThreadPoolExecutor.DelayedWorkQueue经过名字咱们均可以猜到这个是一个延时工做队列。
由于ScheduledThreadPoolExecutor的最大线程是Integer.MAX_VALUE,并且根据源码能够看到execute和submit其实都是调用schedule这个方法,并且延时时间都是指定为0,因此调用execute和submit的任务都直接被执行。算法

Executors 也提供了ScheduledThreadPoolExecutor建立方式

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

ScheduledThreadPoolExecutor 提供了3种延迟执行策略缓存

  1. schedule(commod,delay,unit) ,这个方法是说系统启动后,须要等待多久执行,delay是等待时间。只执行一次,没有周期性。服务器

  2. scheduleAtFixedRate(commod,initialDelay,period,unit),固定速率执行周期任务。这个是以period为固定周期时间,按照必定频率来重复执行任务,initialDelay是说系统启动后,须要等待多久才开始执行。并发

  3. scheduleWithFixedDelay(commod,initialDelay,delay,unit),固定延迟执行周期任务。这个是以delay为固定延迟时间,按照必定的等待时间来执行任务,initialDelay意义与上面的相同。函数

3. ForkJoinPool

在Java 7中引入了一种新的线程池:ForkJoinPool。
它同ThreadPoolExecutor同样,也实现了Executor和ExecutorService接口。它使用了一个无限队列来保存须要执行的任务,而线程的数量则是经过构造函数传入,若是没有向构造函数中传入但愿的线程数量,那么当前计算机可用的CPU数量会被设置为线程数量做为默认值。spa

Executors 提供了 ForkJoinPool 的建立方式

public static ExecutorService newWorkStealingPool() {
    return new ForkJoinPool
        (Runtime.getRuntime().availableProcessors(),
         ForkJoinPool.defaultForkJoinWorkerThreadFactory,
         null, true);
}

并发数默认为当前系统cpu个数。线程

public static ExecutorService newWorkStealingPool(int parallelism) {
    return new ForkJoinPool
        (parallelism,
        ForkJoinPool.defaultForkJoinWorkerThreadFactory,
        null, true);
}

也能够指定并行数。code

相关文章
相关标签/搜索