Executors类
这个类包含了所有的线程池静态工厂方法,我们一般使用工厂方法之一来创建一个线程池。
ExecutorService接口
接口 java.util.concurrent.ExecutorService 表述了异步执行的机制,并且可以让任务在后台执行。一个 ExecutorService 实例因此特别像一个线程池。事实上,在 java.util.concurrent 包中的 ExecutorService 的实现就是一个线程池的实现。
任务委托

一旦线程把任务委托给 ExecutorService,该线程就会继续执行与运行任务无关的其它任务。
ExecutorService的创建
newFixedThreadPool()
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
newFixedThreadPool创建一个固定长度的线程池,每当提交一个任务就创建一个线程,直到线程池的最大数量,这时线程池规模将不再变化(如果某个线程发生了未预期的Exception而结束,那么线程池会补充一个新的线程)
newSingleThreadExecutor()
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
newSingleThreadExecutor是一个单线程的Executor,它创建单个工作者线程来执行任务,如果这个县城异常结束,会创建另一个线程来代替。能确保依照任务在队列中的顺序来执行任务。
newCachedThreadPool()
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);
}
newCachedThreadPool将创建一个可缓存的线程池,这个工厂方法很重要,是个无界线程池,我们将会专门在另一篇文章讲这个方法。
如果线程池当前规模超过了处理需求时,将回收空闲的线程,当需求增加时,则可以添加新的线程,规模不u你在任何限制。
newScheduledThreadPool()
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
创建一个固定长度的线程池,而且以延迟或定时的方式来执行任务,类似于Timer。
ExecutorService使用方法
主要是几个方法的使用,具体看我线程池的第一篇文章
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
submit();
invokeAny();
invokeAll();
execute();
execute()
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
executorService.shutdown();
使用这种方式没有办法获取执行 Runnable 之后的结果,如果你希望获取运行之后的返回值,就必须使用 接收 Callable 参数的 execute() 方法,后者将会在下文中提到。
submit()
Future future = executorService.submit(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
//如果任务结束执行则返回 null
System.out.println("future.get()=" + future.get());
方法 submit(Callable) 和方法 submit(Runnable) 比较类似,但是区别则在于它们接收不同的参数类型。Callable 的实例与 Runnable 的实例很类似,但是 Callable 的 call() 方法可以返回壹個结果。方法 Runnable.run() 则不能返回结果。
Callable 的返回值可以从方法 submit(Callable) 返回的 Future 对象中获取。如下是一个 ExecutorService Callable 的样例:
Future future = executorService.submit(new Callable(){
public Object call() throws Exception {
System.out.println("Asynchronous Callable");
return "Callable Result";
}
});
System.out.println("future.get() = " + future.get());
上述样例代码会输出如下结果:
Asynchronous Callable
future.get() = Callable Result
关闭服务
当使用 ExecutorService 完毕之后,我们应该关闭它,这样才能保证线程不会继续保持运行状态。
举例来说,如果你的程序通过 main() 方法启动,并且主线程退出了你的程序,如果你还有一个活动的 ExecutorService 存在于你的程序中,那么程序将会继续保持运行状态。存在于 ExecutorService 中的活动线程会阻止Java虚拟机关闭。
为了关闭在 ExecutorService 中的线程,你需要调用 shutdown() 方法。ExecutorService 并不会马上关闭,而是不再接收新的任务,一旦所有的线程结束执行当前任务,ExecutorServie 才会真的关闭。所有在调用 shutdown() 方法之前提交到 ExecutorService 的任务都会执行。
如果你希望立即关闭 ExecutorService,你可以调用 shutdownNow() 方法。这个方法会尝试马上关闭所有正在执行的任务,并且跳过所有已经提交但是还没有运行的任务。但是对于正在执行的任务,是否能够成功关闭它是无法保证的,有可能他们真的被关闭掉了,也有可能它会一直执行到任务结束。这是一个最好的尝试。
Executors类
这个类包含了所有的线程池静态工厂方法,我们一般使用工厂方法之一来创建一个线程池。
ExecutorService接口
接口 java.util.concurrent.ExecutorService 表述了异步执行的机制,并且可以让任务在后台执行。一个 ExecutorService 实例因此特别像一个线程池。事实上,在 java.util.concurrent 包中的 ExecutorService 的实现就是一个线程池的实现。
任务委托
一旦线程把任务委托给 ExecutorService,该线程就会继续执行与运行任务无关的其它任务。
ExecutorService的创建
newFixedThreadPool()
newFixedThreadPool创建一个固定长度的线程池,每当提交一个任务就创建一个线程,直到线程池的最大数量,这时线程池规模将不再变化(如果某个线程发生了未预期的Exception而结束,那么线程池会补充一个新的线程)
newSingleThreadExecutor()
newSingleThreadExecutor是一个单线程的Executor,它创建单个工作者线程来执行任务,如果这个县城异常结束,会创建另一个线程来代替。能确保依照任务在队列中的顺序来执行任务。
newCachedThreadPool()
newCachedThreadPool将创建一个可缓存的线程池,这个工厂方法很重要,是个无界线程池,我们将会专门在另一篇文章讲这个方法。
如果线程池当前规模超过了处理需求时,将回收空闲的线程,当需求增加时,则可以添加新的线程,规模不u你在任何限制。
newScheduledThreadPool()
创建一个固定长度的线程池,而且以延迟或定时的方式来执行任务,类似于Timer。
ExecutorService使用方法
主要是几个方法的使用,具体看我线程池的第一篇文章
execute()
使用这种方式没有办法获取执行 Runnable 之后的结果,如果你希望获取运行之后的返回值,就必须使用 接收 Callable 参数的 execute() 方法,后者将会在下文中提到。
submit()
方法 submit(Callable) 和方法 submit(Runnable) 比较类似,但是区别则在于它们接收不同的参数类型。Callable 的实例与 Runnable 的实例很类似,但是 Callable 的 call() 方法可以返回壹個结果。方法 Runnable.run() 则不能返回结果。
Callable 的返回值可以从方法 submit(Callable) 返回的 Future 对象中获取。如下是一个 ExecutorService Callable 的样例:
上述样例代码会输出如下结果:
关闭服务
当使用 ExecutorService 完毕之后,我们应该关闭它,这样才能保证线程不会继续保持运行状态。
举例来说,如果你的程序通过 main() 方法启动,并且主线程退出了你的程序,如果你还有一个活动的 ExecutorService 存在于你的程序中,那么程序将会继续保持运行状态。存在于 ExecutorService 中的活动线程会阻止Java虚拟机关闭。
为了关闭在 ExecutorService 中的线程,你需要调用 shutdown() 方法。ExecutorService 并不会马上关闭,而是不再接收新的任务,一旦所有的线程结束执行当前任务,ExecutorServie 才会真的关闭。所有在调用 shutdown() 方法之前提交到 ExecutorService 的任务都会执行。
如果你希望立即关闭 ExecutorService,你可以调用 shutdownNow() 方法。这个方法会尝试马上关闭所有正在执行的任务,并且跳过所有已经提交但是还没有运行的任务。但是对于正在执行的任务,是否能够成功关闭它是无法保证的,有可能他们真的被关闭掉了,也有可能它会一直执行到任务结束。这是一个最好的尝试。