Java ExecutorService使用线程池

本文概述

  • Java ExecutorService的方法
  • Java ExecutorService的简单程序
  • 如何使用Java ExecutorService
  • 如何关闭ExecutorService
Java ExecutorService是允许我们异步在线程上执行任务的接口。 Java ExecutorService接口位于java.util.concurrent包中。 ExecutorService帮助维护线程池并为其分配任务。如果任务数大于可用线程数, 它还提供了将任务排队的功能, 直到有可用线程可用为止。
Java ExecutorService使用线程池

文章图片
Java ExecutorService的方法
方法 描述
boolean awaitTermination(long timeout, TimeUnit unit) 此方法将阻止任务进入ExecutorService, 直到关闭请求后所有任务都已完成, 或者发生给定的超时, 或者当前线程被中断, 以先发生的为准。
< T> 列表invokeAll(Collection < ?扩展了Callable < T > > 任务) 此方法执行给定的任务列表, 并返回包含所有任务完成时的结果的期货列表。
< T> 列表invokeAll(Collection < ?扩展了Callable < T > > 任务, 超时, TimeUnit单位) 此方法执行给定的任务列表, 并返回期货列表, 其中包含完成或超时到期时所有任务的结果(以先发生者为准)。
< T> T invokeAny(Collection < ?扩展了Callable < T > > 任务) 该方法执行给定任务的列表, 并返回一个完成的任务的结果, 而不会引发任何异常。
< T> T invokeAny(Collection < ?扩展了Callable < T > > 任务, 超时, TimeUnit单位) 此方法执行给定任务的列表, 并返回一个任务的结果, 该任务在超时之前完成而不会引发任何异常。
boolean isShutdown() 此方法返回是否关闭给定的执行器。
boolean isTerminated() 如果关闭后所有任务都已执行, 则此方法返回true。
void shutdown() 此方法允许完成先前提交给ExecutorService的任务, 并且不允许其他任何任务被接受。
List shutdownNow() 此方法停止所有正在执行的任务, 停止执行排队的任务, 并返回排队的任务列表。
< T> 将来< T> 提交(可调用< T> 任务) 此方法提交一个执行返回值的任务并返回Future, 该Future表示任务的未决结果。
将来< ?> 提交(可运行任务) 此方法提交要执行的任务, 并返回表示该任务的Future。成功完成后返回null。
< T> 将来< T> 提交(可运行任务, T结果) 此方法提交要执行的任务, 并返回表示该任务的Future。
Java ExecutorService的简单程序
public class ExecutorServiceExample { public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.execute(new Runnable() {@Overridepublic void run() {System.out.println("ExecutorService"); }}); executorService.shutdown(); }}

输出:
Java ExecutorService使用线程池

文章图片
在该程序中, 我们将创建一个具有10个线程的ExecutorService, 并为其分配一个匿名的可运行实现, 该实现执行打印“ ExecutorService”的任务, 并且在其任务结束后, 我们将关闭executor服务。
如何使用Java ExecutorService 实例化ExecutorService
我们可以使用Java ExecutorService创建一个线程, 一个线程池或一个预定的线程池。 Executors类提供了如下的工厂方法来实例化ExecutorService:
ExecutorService executorService1 = Executors.newSingleThreadExecutor(); //Creates //a ExecutorService object having a single thread.ExecutorService executorService2 = Executors.newFixedThreadPool(10); // Creates a //ExecutorService object having a pool of 10 threads.ExecutorService executorService3 = Executors.newScheduledThreadPool(10); //Creates a scheduled thread pool executor with 10 threads. In scheduled thread //pool, we can schedule tasks of the threads.

将任务分配给ExecutorServices
要将任务分配给ExecutorService, 我们可以使用以下方法:
  • 执行(可运行任务)
  • 提交(可运行任务)/提交(可调用< T> 任务)
  • invokeAny(Collection < ?扩展了Callable < T > > 任务)
  • invokeAll(Collection < ?扩展了Callable < T > > 任务)
使用execute()方法将任务分配给ExecutorService的示例
Java ExecutorService的execute()方法接受一个可运行的对象, 并异步执行其任务。调用execute方法之后, 我们调用shutdown方法, 该方法将阻止任何其他任务在executorService中排队。
public class ExecutorServiceExample { public static void main(String[] args) {ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() {@Overridepublic void run() {System.out.println("ExecutorService"); }}); executorService.shutdown(); }}

输出:
ExecutorService

使用Submit()将任务分配给ExecutorService的示例
Submit()方法接受一个可运行对象, 并返回一个Future对象。稍后, 该对象用于检查Runnable的状态是否已完成执行。
public class ExecutorServiceExample { public static void main(String[] args) {ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.submit(new Runnable() {@Overridepublic void run() {System.out.println("ExecutorService"); }}); }}

使用invokeAny()方法将任务分配给ExecutorService的示例
invokeAny()方法采用Callablle对象或实现Callable的类的对象的集合。此方法返回可调用对象的将来对象, 该对象将首先成功执行。
public class ExecutorServiceExample { public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService executorService = Executors.newSingleThreadExecutor(); Set< Callable< String> > callables = new HashSet< Callable< String> > (); callables.add(new Callable< String> () {public String call() throws Exception {return "Task 1"; }}); callables.add(new Callable< String> () {public String call() throws Exception {return "Task 2"; }}); callables.add(new Callable< String> () {public String call() throws Exception {return "Task 3"; }}); String result = executorService.invokeAny(callables); System.out.println("result = " + result); executorService.shutdown(); }}

输出:
result = Task 1

结果将Task 1存储为第一个可成功执行的第一个可调用对象。
使用invokeAll()方法将任务分配给ExecutorService的示例
invokeAll()方法接收具有任务的Callable对象的Collection, 并返回包含所有任务结果的Future对象的列表。
public class ExecutorServiceExample { public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService executorService = Executors.newSingleThreadExecutor(); Set< Callable< String> > callables = new HashSet< Callable< String> > (); callables.add(new Callable< String> () {public String call() throws Exception {return "Task 1"; }}); callables.add(new Callable< String> () {public String call() throws Exception {return "Task 2"; }}); callables.add(new Callable< String> () {public String call() throws Exception {return "Task 3"; }}); java.util.List< Future< String> > futures = executorService.invokeAll(callables); for(Future< String> future : futures){System.out.println("future.get = " + future.get()); }executorService.shutdown(); }}

输出:
future.get = Task 1future.get = Task 3future.get = Task 2

如何关闭ExecutorService 一旦完成了给ExecutorService的任务, 就必须将其关闭, 因为ExecutorService在不同的线程上执行任务。如果我们不关闭ExecutorService, 线程将继续运行, 并且JVM将不会关闭。
【Java ExecutorService使用线程池】关闭过程可以通过以下三种方法完成:
  • shutdown()方法
  • shutdownNow()方法
  • awaitTermination()方法

    推荐阅读