1:JDK中的线程池
1.1:Executor
- Executor意为执行器的意思
public interface Executor {
void execute(Runnable command);
}
1.2:ExcutorService
public interface ExecutorService extends Executor {
启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
void shutdown();
如果此执行程序已关闭,则返回 true。
boolean isShutdown();
如果关闭后所有任务都已完成,则返回 true。
boolean isTerminated();;
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
提交一个 Runnable 任务用于执行,
Future<?> submit(Runnable task);
}
1.3:ScheduledExecutorService
public interface ScheduledExecutorService extends ExecutorService {
创建并执行在给定延迟后启用的 ScheduledFuture。
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
创建并执行在给定延迟后启用的一次性操作。
public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay, TimeUnit unit);
创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推,(头头),
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。(头尾)
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
}
对于FixedRate方式来说,任务调度的频率是一定的。它是以上一个任务开始执行时间为起点,之后的period时间,调度下一次任务。而FixDelay则是在上一个任务结束后,再经过delay时间进行任务调度。
- ScheduledExecutorService不会让同一种任务堆叠出现,如果延迟两秒,但是任务是8秒,那么会在上一次执行完后立即执行线依次任务
- ScheduledExecutorService设置的线程数量不是说可以产生堆叠,而是可以提交多少种定时任务,每种任务使用一个线程区定时执行
1.4:Executors
public static ExecutorService newFixedThreadPool(int nThreads)
-该方法返回一个固定线程数量的线程池。该线
程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线
程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程
空闲时,便处理在任务队列中的任务。public static ExecutorService newSingleThreadExecutor()
-该方法返回一个只有一个线程的线程池。
若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程
空闲,按先入先出的顺序执行队列中的任务。public static ExecutorService newCachedThreadPool()
- :该方法返回一个可根据实际情况调整线程数量
的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使
用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线
程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。
- :该方法返回一个可根据实际情况调整线程数量
public static ScheduledExecutorService=newSingleThreadScheduledExecutor()
- 该方法返回一个
ScheduledExecutorService对象,线程池大小为1。
ScheduledExecutorService接口在ExecutorService接口之上扩展了在给定
时间执行某任务的功能,如在某个固定的延时之后执行,或者周期性执行某个任务。
- 该方法返回一个
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
- 该方法也返回一个
ScheduledExecutorService对象,但该线程池可以指定线程数量。
ScheduledExecutorService就是1.3中的那个有三个常用方法
- 该方法也返回一个
2:ThreadPoolExecutor
对于核心的几个线程池,无论是newFixedThreadPool()方法、
newSingleThreadExecutor()还是newCachedThreadPool()方法,虽然看起来创
建的线程有着完全不同的功能特点,但其内部实现均使用了ThreadPoolExecutor
实现。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
- 另外两个定时的没有使用这个,而是返回ScheduledThreadPoolExecutor实例
由以上线程池的实现代码可以看到,它们都只是ThreadPoolExecutor类的封
装。为何ThreadPoolExecutor有如此强大的功能呢?来看一下
ThreadPoolExecutor最重要的构造函数:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
函数的参数含义如下。
- corePoolSize:指定了线程池中的线程数量。
- maximumPoolSize:指定了线程池中的最大线程数量。
- keepAliveTime:当线程池线程数量超过corePoolSize时,多余的空闲线程的
存活时间。即,超过corePoolSize的空闲线程,在多长时间内,会被销毁。 - unit: keepAliveTime的单位。
- workQueue:任务队列,被提交但尚未被执行的任务。
- threadFactory:线程工厂,用于创建线程,一般用默认的即可。
- handler:拒绝策略。当任务太多来不及处理,如何拒绝任务。