个性化阅读
专注于IT技术分析

Java 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() {
			
			@Override
			public 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() {
			
			@Override
			public 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() {
			
			@Override
			public 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 1
future.get = Task 3
future.get = Task 2

如何关闭ExecutorService

一旦完成了给ExecutorService的任务, 就必须将其关闭, 因为ExecutorService在不同的线程上执行任务。如果我们不关闭ExecutorService, 线程将继续运行, 并且JVM将不会关闭。

关闭过程可以通过以下三种方法完成:

  • shutdown()方法
  • shutdownNow()方法
  • awaitTermination()方法

赞(0)
未经允许不得转载:srcmini » Java ExecutorService使用线程池

评论 抢沙发

评论前必须登录!