概念理解
所谓线程池,就是预先创建并存放线程的一个类。当我们的项目中,需要大量使用线程,或者当初始化线程的时间或内存消耗过大时,就可以使用线程池预创建一批线程,以备需要时调用。
ExecutorService
Executor是最顶端的接口,ExecutorService接口继承了Executor接口,提供了一些管理线程的方法,可以来生和追踪一个或多个异步的线程。
一个ExecutorService服务可以被关闭,此时将阻止新的任务被创建。这里有两种关闭方法:shutdown()和shutdownNow()。shutdown()方法将会允许之前创建的所有线程任务运行至结束,然后关闭ExecutorService,而shutdownNow()则会阻止在waiting状态的任务启动,并尝试强制关闭正在运行中的任务。我们应及时关闭不使用的ExecutorService来释放资源。
submit 方法继承自 Executor.execute(Runable),用来执行任务。invokeAny 和 invokeAll方法是最常见的用来执行批量任务的方法,invokeAny方法会返回最先执行结束的结果,而invokeAll方法则会等所有任务结束或超时后,统一返回他们的结果和状态。
应用示例
下面的例子就是调用thread pool中的thread来处理到来的请求。例子中使用 Executors.newFixedThreadPool(int)来初始化线程池的容量。
class NetworkService implements Runnable {
private final ServerSocket serverSocket;
private final ExecutorService pool;
public NetworkService(int port, int poolSize)
throws IOException {
serverSocket = new ServerSocket(port);
pool = Executors.newFixedThreadPool(poolSize);
}
public void run() { // run the service
try {
for (;;) {
pool.execute(new Handler(serverSocket.accept()));
}
} catch (IOException ex) {
pool.shutdown();
}
}
}
class Handler implements Runnable {
private final Socket socket;
Handler(Socket socket) { this.socket = socket; }
public void run() {
// read and service request on socket
}
}
下面这个例子分两步结束一个ExecutorService 。首先调用shutdown方法阻止新建任务,然后调用shutdownNow方法,取消所有未完成的任务。
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
其它方法
boolean awaitTermination(long timeout, TimeUnit unit)
在shutdown方法执行后,判断是否所有任务都已经结束。如果已经全部结束,则返回true;如果在timeout时间内未全部结束,则返回false
boolean isShutdown()
判断是否executor已经成功结束
boolean isTerminated()
判断是否所有任务都己经结束
之后我们将详细介绍ThreadPoolExecutor类及其使用方法。