ExecutorService深入理解

来源:互联网 发布:网络延迟怎么解决 编辑:程序博客网 时间:2024/06/02 01:24

ExecutorService是Executor直接的扩展接口,也是最常用的线程池接口,我们通常见到的线程池定时任务线程池都是它的实现类。

原文:

An Executor that provides methods to manage termination and methods
that can produce a Future for tracking progress of one or more
asynchronous tasks.

Executor的实现提供的一些方法可以返回一个 Future , 通过它我们可以跟踪到异步任务的执行和停止。

原文:

An ExecutorService can be shut down, which will cause it to reject new
tasks. Two different methods are provided for shutting down an
ExecutorService. The shutdown method will allow previously submitted
tasks to execute before terminating, while the shutdownNow method
prevents waiting tasks from starting and attempts to stop currently
executing tasks. Upon termination, an executor has no tasks actively
executing, no tasks awaiting execution, and no new tasks can be
submitted. An unused ExecutorService should be shut down to allow
reclamation of its resources.

ExecutorService(线程池)可以被关闭来拒绝新任务。有两个不同的方法来关闭。
shutdown方法 在关闭 ExecutorService 之前等待提交的任务执行完成。
shutdownNow方法 会阻止开启新的任务并且尝试停止当前正在执行的线程,一旦调用该方法,线程池中将没有激活的任务,没有等待执行的任务,也没有新任务提交。
没有任务执行的ExecutorService将会被回收。

原文:

Method submit extends base method Executor.execute(Runnable) by
creating and returning a Future that can be used to cancel execution
and/or wait for completion. Methods invokeAny and invokeAll perform
the most commonly useful forms of bulk execution, executing a
collection of tasks and then waiting for at least one, or all, to
complete. (Class ExecutorCompletionService can be used to write
customized variants of these methods.)

方法submit扩展了Executor.execute(Runnable) 方法, 创建并返回一个 Future 结果,这个Future可以取消任务的执行或者等待完成得到返回值。
方法invokeAny and invokeAll 可以执行一组任务,等待至少一个任务或者多个任务完成(ExecutorCompletionService扩展了这些方法的实现)。

原文:

The Executors class provides factory methods for the executor services
provided in this package.
Usage Examples Here is a sketch of a network service in which threads
in a thread pool service incoming requests. It uses the preconfigured
Executors.newFixedThreadPool factory method:

下面是一个网络服务的简单例子,使用线程池管理线程来服务请求,使用预定大小的工厂方法 Executors.newFixedThreadPool

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   } }}

原文:

The following method shuts down an ExecutorService in two phases,
first by calling shutdown to reject incoming tasks, and then calling
shutdownNow, if necessary, to cancel any lingering tasks:

下面使用2种方法来关闭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();   } }}

原文:

Memory consistency effects: Actions in a thread prior to the
submission of a Runnable or Callable task to an ExecutorService
happen-before any actions taken by that task, which in turn
happen-before the result is retrieved via Future.get().

内存一致性影响:提交给ExecutorService中同的一个线程中的任务满足happen-before(偏序关系),就是说如果一个线程先提交,那么它也应该先执行。
相应的返回结果也保证这种happen-before(偏序关系),先提交的任务也先通过Future.get().得到结果。

以下是这个接口定义的方法:

void shutdown();

发起一个关闭请求,已提交的任务会执行,但不会接受新的任务请求了。
这个方法不会等待已提交的任务全部执行完成,如果你希望这样做,可以使用awaitTermination方法


List<Runnable> shutdownNow();

这个方法会停掉所有执行中的任务,取消等待中的任务,返回等待执行的任务 的list
方法不会等待执行中的任务停止,如果你希望这样做,可以使用awaitTermination方法


boolean isShutdown();

如果线程池停止完成返回true


boolean isTerminated();

如果线程池停止完成返回true
当所有的任务都停止了,返回true, 注意:只有调用 shutdown 或者 shutdownNow 才返回true


boolean awaitTermination(long timeout, TimeUnit unit)        throws InterruptedException;

调用此方法,在shutdown请求发起后,除非以下任何一种情况发生,否则当前线程将一直到阻塞。
1、所有任务执行完成
2、超过超时时间
3、当前线程被中断


<T> Future<T> submit(Callable<T> task);

提交一个带有返回值的任务(Callable),返回值为Future,表示了任务的执行完成结果,Future.get()方法返回成功执行后的结果。
如果你想要阻塞当前线程知道执行完成返回结果,那么你可以这样做:
result = exec.submit(aCallable).get();


<T> Future<T> submit(Runnable task, T result);

提交一个Runnable任务执行,返回一个Future做为任务task的代理,Future.get()方法在执行成功后可以返回结果。
Runnable task 提交的任务
T results 执行的结果


 Future<?> submit(Runnable task);

提交一个Runnable任务执行,返回一个Future做为任务task的代理,Future.get()方法在执行成功后可以返回结果。


 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;

执行一组任务,返回一个Future的list,其中的Future持有任务执行完成的结果和状态
对于每一个返回的结果,Future.isDone = true
完成的任务可能正常结束或者异常结束,
如果在任务执行过程中参数Collection改变了,那么返回结果是不确定的。


<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)        throws InterruptedException;

执行一组任务,返回一个Future的list,其中的Future持有任务执行完成的结果和状态
如果所有任务执行完成或者超时,对于每一个返回的结果中,Future.isDone = true
当返回时,未执行完成的任务被取消,完成的任务可能正常结束或者异常结束,
如果在任务执行过程中参数Collection改变了,那么返回结果是不确定的。


<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;

执行一组任务,当成功执行完一个任务(没有抛异常),就返回结果,不论正常返回还是异常结束,未执行的任务都会被取消。
如果在任务执行过程中参数Collection改变了,那么返回结果是不确定的。


<T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;

执行一组任务,在未超时情况下,当成功执行完一个任务(没有抛异常),就返回结果。不论正常返回还是异常结束,未执行的任务都会被取消。
如果在任务执行过程中参数Collection改变了,那么返回结果是不确定的。


以上就是一个线程池基本的功能了。之后的实现类都是根据这个规范来做的,理解这个对理解之后的各种线程池很有帮助

    0 0