Java中四种具有不同功能常见的线程池。他们都是直接或者间接配置 ThreadPoolExecutor来实现他们各自的功能。这四种线程池分别是newFixedThreadPool, newCachedThreadPool ,
newScheduledThreadPool和 newSingleThreadExecutor 。这四个线程池可以通过 Executors 类获取。
1. newFixedThreadPool
通过 Executors 中的 newFixedThreadPool 方法来创建,该线程池是一种线程数量固定的线程池。
ExecutorService service = Executors.newFixedThreadPool(4);
在这个线程池中,所容纳的最大线程数就是就是设置的核心线程数。如果线程池中的线程处于空闲状态的话,并不会被回收,除非是这个线程池被关闭。如果所有的线程都处于活动状态的话,新任务就会处于等待状态,直到有线程空闲出来。
2. newCachedThreadPool
通过 Executors 中的 newCachedThreadPool 方法来创建。
public static ExecutorService newCachedThreadPool()
{ return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L,
TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}
通过 上面的 newCachedThreadPool 方法在这里我们可以看出它的核心线程数为 0 , 线程池的最大线程数 Integer.MAX_VALUE 。而 Integer.MAX_VALUE 是一个很大的数,也差不多可以说 这个线程池中的最大线程数可以任意大。
当线程池中的线程都处于活动状态的时候,线程池就会创建一个新的线程来处理任务。该线程池中的线程超时时长为60 秒,所以当线程处于闲置状态超过 60 秒的时候便会被回收。 这也就意味着若是整个线程池的线程都处于闲置状态超过60 秒以后,在newCachedThreadPool 线程池中是不存在任何线程的,所以这时候它几乎不占用任何的系统资源。
3. newScheduledThreadPool
通过 Executors 中的 newScheduledThreadPool 方法来创建。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
它的核心线程数是固定的,对于非核心线程几乎可以说是没有限制的,并且当非核心线程处于限制状态的时候就会立即被回收。
创建一个可定时执行或周期执行任务的线程池:
ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
service.schedule(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + "延迟三秒执行");
}
}, 3, TimeUnit.SECONDS);
service.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + "延迟三秒后每隔2秒执行");
}
}, 3, 2, TimeUnit.SECONDS);
输出结果:
pool-1-thread-2 延迟三秒后每隔 2 秒执行
pool-1-thread-1 延迟三秒执行
pool-1-thread-1 延迟三秒后每隔 2 秒执行
pool-1-thread-2 延迟三秒后每隔 2 秒执行
pool-1-thread-2 延迟三秒后每隔 2 秒执行
schedule(Runnable command, long delay, TimeUnit unit) :延迟一定时间后执行Runnable 任务;
schedule(Callable callable, long delay, TimeUnit unit) :延迟一定时间后执行Callable 任务;
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) :延迟一定时间后,以间隔 period 时间的频率周期性地执行任务;
scheduleWithFixedDelay(Runnable command, long initialDelay, long delay,TimeUnit unit) : 与 scheduleAtFixedRate() 方法很类似,但是不同的是scheduleWithFixedDelay()方法的周期时间间隔是以上一个任务执行结束到下一个 任务开始执行的间隔,而scheduleAtFixedRate() 方法的周期时间间隔是以上一个任务开始执行到下一个任务开始执行的间隔,也就是这一些任务系列的触发时间都是可预知的。
ScheduledExecutorService 功能强大,对于定时执行的任务,建议多采用该方法。
4. newSingleThreadExecutor
通过 Executors 中的 newSingleThreadExecutor 方法来创建,在这个线程池中只有一个核心线程,对于任务队列没有大小限制,也就意味着这一个任务处于活动状态时,其他任务都会在任务队列中排队等候依次执行。
newSingleThreadExecutor 将所有的外界任务统一到一个线程中支持,所以在这个任务执行之间我们不需要处理线程同步的问题。
public static ExecutorService newSingleThreadExecutor(){
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()));
}