在Java中能够经过线程池来达到线程复用的目的。在线程池中,线程已经预先被建立好,当线程执行完一个任务后,并不当即被销毁,而是回到线程池中,继续执行其它任务。这样能够提高系统的执行效率,由于建立和销毁线程都须要时间。java
java.uitl.concurrent包是Java多线程并发工具包,此包下面有不少关于线程池的工具类。缓存
(1)Executor:一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable command)。多线程
(2)ExecutorService:ExecutorService继承了Executor。是一个比Executor使用更普遍的子类接口,其提供了生命周期管理的方法,以及可跟踪一个或多个异步任务执行情况返回Future的方法。并发
(3)AbstractExecutorService:AbstractExecutorService实现了ExecutorService接口。异步
(4)ScheduledExecutorService:与AbstractExecutorService同样实现了ExecutorService接口。它是一个可定时调度任务的接口。ide
(5)ScheduledThreadPoolExecutor:ScheduledExecutorService的实现,一个可定时调度任务的线程池。工具
(6)ThreadPoolExecutor:线程池,继承了AbstractExecutorService。能够经过调用Executors如下静态工厂方法来建立线程池并返回一个ExecutorService对象。oop
(7)Executors:Executors 类提供工厂和使用方法用来建立不一样类型的线程池。ui
public class ThreadPoolExecutor extends AbstractExecutorService { public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler); }
下面解释下一下构造器中各个参数的含义:spa
(1)corePoolSize:核心池的大小,这个参数跟后面讲述的线程池的实现原理有很是大的关系。在建立了线程池后,默认状况下,线程池中并无任何线程,而是等待有任务到来才建立线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就能够看出,是预建立线程的意思,即在没有任务到来以前就建立corePoolSize个线程或者一个线程。默认状况下,在建立了线程池后,线程池中的线程数为0,当有任务来以后,就会建立一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
(2)maximumPoolSize:线程池最大线程数,这个参数也是一个很是重要的参数,它表示在线程池中最多能建立多少个线程;
(3)keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认状况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起做用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,若是一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。可是若是调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起做用,直到线程池中的线程数为0;
(3)unit:参数keepAliveTime的时间单位;
(4)workQueue:一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,通常来讲,这里的阻塞队列有如下几种选择:ArrayBlockingQueue、LinkedBlockingQueue和SynchronousQueue。 ArrayBlockingQueue和PriorityBlockingQueue使用较少,通常使用LinkedBlockingQueue和Synchronous。线程池的排队策略与BlockingQueue有关。
(5)threadFactory:线程工厂,主要用来建立线程;
(6)handler:表示当拒绝处理任务时的策略,有如下四种取值:
public class Executors { // 建立固定线程数目的线程池 public static ExecutorService newFixedThreadPool(int nThreads) {}; // 建立固定线程数目的线程池 public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {}; // 建立单一线程数目的线程池 public static ExecutorService newSingleThreadExecutor() {}; // 建立单一线程数目的线程池 public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {}; // 建立缓存线程数目的线程池 public static ExecutorService newCachedThreadPool() {}; // 建立缓存线程数目的线程池 public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {}; /** Cannot instantiate. */ private Executors() {} }
下面解释下一下构造器中各个参数的含义:
(1)nThreads:建立线程的数目;
(2)threadFactory:工厂新建时使用的线程工厂;
(1)线程池:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * 线程池的使用实例 * * @author xiao */ public class ThreadPoolTest { public static void main(String[] args) { // ExecutorService threadPool = Executors.newFixedThreadPool(3); // 建立固定大小的线程池:起3个线程的线程池(固定线程数的线程池) // ExecutorService threadPool = Executors.newCachedThreadPool(); // 建立缓存线程池:线程池的线程数目随实际运行线程的数目变化而变化 ExecutorService threadPool = Executors.newSingleThreadExecutor(); // 建立单一线程池:线程池中只有一个线程 for (int i = 0; i < 10; i++) { final int task = i; // 须要将task变量设置为final,这样在线程的runnable中才能访问 threadPool.execute(new Runnable() { // 每一个runnable表示一个任务 @Override public void run() { for (int i = 1; i <= 10; i++) { // 此循环中的i和上面循环的i并非同一个方法中的变量,因此不会冲突 System.out.println(Thread.currentThread().getName() + " is loop of " + i + " task for " + task); } } }); } System.out.println("10 tasks have committed! "); threadPool.shutdown();// 线程池中无线程运行时,则关闭线程池 /** * 用线程池启动定时器:调用 ScheduledExecutorServiced的schedule方法, * 返回的ScheduledFuture对象能够取消任务支持间隔重复任务的定时方式, * 不直接支持绝对定时方式,须要转换成相对时间方式 */ Executors.newScheduledThreadPool(3).scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("线程池定时器"); } }, 6, 1, TimeUnit.SECONDS); } }