1. Executor
是一个接口类(异步执行框架),其定义了一个接收Runnable对象的方法execute,,该方法接收一个Runable实例,它用来执行一个任务,任务即一个实现了Runnable接口的类。 Executor基于生产者-消费者模式, 提交任务的操作相当于生产者,执行任务的线程相当于消费者。
源码
public interface Executor {
void execute(Runnable command);
// Runnable任务开辟在新线程中的使用方法为:new Thread(new RunnableTask())).start()
}
使用示例
// 例1:
public class ExecutorImpl1 implements Executor{
public void execute(Runnable r){
new Thread(r).start();
}
}
// 例2:
public class ExecutorImpl2 implements Executor{
public void execute(Runnable r){
r.run();
}
}
2. Executors
源码
构造函数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize
核心池大小,除非设置了
allowCoreThreadTimeOut
否则哪怕线程超过空闲时间,池中也要最少要保留这个数目的线程。 需要注意的是,corePoolSize所需的线程并不是立即创建的,需要在提交任务之后进行创建,所以如果有大量的缓存线程数可以先提交一个空任务让线程池将线程先创建出来,从而提升后续的执行效率。maximumPoolSize
允许的最大线程数。
keepAliveTime
空闲线程空闲存活时间,核心线程需要
allowCoreThreadTimeOut
为true才会退出。unit
与
keepAliveTime
配合,设置keepAliveTime
的单位,如:毫秒、秒。workQueue
线程池中的任务队列。上面提到线程池的主要作用是复用线程来处理任务,所以我们需要一个队列来存放需要执行的任务,在使用池中的线程来处理这些任务,所以我们需要一个任务队列。
threadFactory
当线程池判断需要新的线程时通过线程工程创建线程。
handler
执行被阻止时的处理程序,线程池无法处理。这个与任务队列相关,比如队列中可以指定队列大小,如果超过了这个大小该怎么办呢?JDK已经为我们考虑到了,并提供了4个默认实现。
1. newFixedThreadPool()
// 创建一个定长的线程池,可以控制线程的最大并发数,超出的任务会在队列中等待,直到有线程可用
// 这些线程是可重复使用的,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
/* @param nThreads the number of threads in the pool
* @return the newly created thread pool
* @throws IllegalArgumentException if {@code nThreads <= 0}
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
// @param threadFactory 用于创建新线程的工厂
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
2. newCachedThreadPool ()
// 创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),threadFactory);
}
3. newSingleThreadExecutor ()
创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
// @return the newly created single-threaded Executor
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
}
//@return the newly created single-threaded Executor
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
4. newScheduledThreadPool ()
创建一个指定大小的线程池。此线程池支持定时以及周期性执行任务的需求。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
5. newSingleThreadScheduledExecutor ()
创建一个单线程用于定时以及周期性执行任务的需求。
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1, threadFactory));
}
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
6. newWorkStealingPool
创建一个工作窃取