Java线程池ExecutorService中重要的方法
ExecutorService 介绍
ExecutorService
是java
线程池定义的一个接口,它在java.util.concurrent
包中,在这个接口中定义了和后台任务执行相关的方法。
Java API对
ExecutorService
接口实现有两个,所以这两个即是线程池的具体实现。
1. ThreadPoolExecutor
2. ScheduledThreadPoolExecutor
ExecutorService
还继承了Executor
接口。
实线表示继承,需要表示实现
ExecutorService
的创建
Java
提供了一个工厂类Executors
来创建各种线程池。
- newCachedThreadPool 创建一个可缓存的线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,如果没有可以回收的,则新建线程。
- newFixedThreadPool 创建一个定长的线程池,可控制线程最大并发数,超出的线程会在队列中等待。
- newScheduledThreadPool 创建一个定长线程池,可以定时周期性执行任务。
- newSingleThreadPool 创建一个单线程线程池,它只会用唯一的线程来执行任务,保证所有任务按照指定顺序来执行(FIFO,LIFO)
Executors
是一个工厂类,它所有的方法返回的都是ThreadPoolExecutor
和ScheduledThreadPoolExecutor
这两个类的实例。
ExecutorService
的使用
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new Runnable() {
public void run() {
System.out.println("入门小站");
}
});
executorService.shutdown();
ExecutorService
的执行方法
- execute(Runnable)
- submit(Runnable)
- submit(Callable)
- invokeAny(...)
- invokeAll(...)
execute(Runnable)
无法获取执行结果
接收一个
Runnable
实例,并且异步执行
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
executorService.shutdown();
没有办法获取执行结果。
submit(Runnable)
可以判断任务是否完成
submit(Runnable)
比execute(Runnable)
多返回一个Future
,可以用来判断提交的任务是否执行完成。
Future future = executorService.submit(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
future.get(); //returns null if the task has finished correctly.
如果任务完成,
future.get()
会返回null,future.get
会阻塞。
submit(Callable)
可以获取返回结果
submit(Callable)和submit(Runnable)类似,也会返回一个Future对象,但是除此之外,submit(Callable)接收的是一个Callable的实现,Callable接口中的call()方法有一个返回值,可以返回任务的执行结果,而Runnable接口中的run()方法是void的,没有返回值
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());
如果任务完成,
future.get
会返回Callable
执行返回的结果,同样future.get()
会阻塞。
invokeAny(...)
invokeAny(...)
方法接收的是一个Callable
的集合,执行这个方法不会返回Future,但是会返回所有Callable任务中其中一个任务的执行结果。这个方法也无法保证返回的是哪个任务的执行结果,反正是其中的某一个
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();
每次执行都会返回一个结果,并且返回的结果是变化的,可能会返回“Task2”也可是“Task1”或者其它。
invokeAll(...)
invokeAll(...)与 invokeAny(...)类似也是接收一个Callable集合,但是前者执行之后会返回一个Future的List,其中对应着每个Callable任务执行后的Future对象。
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";
}
});
List<Future<String>> futures = executorService.invokeAll(callables);
for(Future<String> future : futures){
System.out.println("future.get = " + future.get());
}
executorService.shutdown();
线程池ExecutorService
的关闭
如果要关闭ExecutorService中执行的线程,我们可以调用ExecutorService.shutdown()方法。在调用shutdown()方法之后,ExecutorService不会立即关闭,但是它不再接收新的任务,直到当前所有线程执行完成才会关闭,所有在shutdown()执行之前提交的任务都会被执行。
如果我们想立即关闭ExecutorService,我们可以调用ExecutorService.shutdownNow()方法。这个动作将跳过所有正在执行的任务和被提交还没有执行的任务。但是它并不对正在执行的任务做任何保证,有可能它们都会停止,也有可能执行完成。
关注微信公众号:【入门小站】,解锁更多知识点