ExecutorService 介绍
ExecutorService
是java
线程池定义的一个接口,它在java.util.concurrent
包中,在这个接口中定义了和后台任务执行相干的办法。
Java API对ExecutorService
接口实现有两个,所以这两个即是线程池的具体实现。
1. ThreadPoolExecutor2. 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()办法。这个动作将跳过所有正在执行的工作和被提交还没有执行的工作。然而它并不对正在执行的工作做任何保障,有可能它们都会进行,也有可能执行实现。
关注微信公众号:【入门小站】,解锁更多知识点