public interface Executor {
在将来的某个时间执行给定的可运行的任务。该可运行的任务可以在新线程、池线程或调用线程中执行,由Executor实现决定。
参数: command–可运行的任务
投掷: RejectedExecutionException–如果无法接受执行此任务 NullPointerException–如果命令为空
void execute(Runnable command);
}
public interface ExecutorService extends Executor {
1、停止接收新的submit的任务;
2、已经提交的任务(包括正在跑的和队列中等待的),会继续执行完成;
3、等到第2步完成后,才真正停止;void shutdown();
}
实例如下:
public class ThreadPoolExecutorCloseTest {public static void main(String[] args) {ExecutorService executorService = new ThreadPoolExecutor(10,20,30,TimeUnit.SECONDS,new ArrayBlockingQueue<>(1),Thread::new,new ThreadPoolExecutor.AbortPolicy());IntStream.range(0, 20).boxed().forEach(i -> {executorService.execute(() -> {try {TimeUnit.SECONDS.sleep(10);System.out.println(Thread.currentThread().getName() + " [ " + i + " ] finish done.");} catch (InterruptedException e) {e.printStackTrace();}});});/*** 1、停止接收新的submit的任务;* 2、已经提交的任务(包括正在跑的和队列中等待的)会继续执行完成;* 3、等到第2步完成后,才真正停止;*/executorService.shutdown();System.out.println("==============over==============");}
}
线程真正停止了!
==============over==============
Thread-15 [ 16 ] finish done.
Thread-9 [ 9 ] finish done.
Thread-16 [ 17 ] finish done.
Thread-7 [ 7 ] finish done.
Thread-12 [ 13 ] finish done.
Thread-5 [ 5 ] finish done.
Thread-4 [ 4 ] finish done.
Thread-3 [ 3 ] finish done.
Thread-1 [ 1 ] finish done.
Thread-11 [ 12 ] finish done.
Thread-6 [ 6 ] finish done.
Thread-17 [ 18 ] finish done.
Thread-10 [ 11 ] finish done.
Thread-13 [ 14 ] finish done.
Thread-18 [ 19 ] finish done.
Thread-8 [ 8 ] finish done.
Thread-14 [ 15 ] finish done.
Thread-2 [ 2 ] finish done.
Thread-0 [ 0 ] finish done.
Thread-12 [ 10 ] finish done.Process finished with exit code 0
当前线程阻塞,直到:
1、等所有已提交的任务(包括正在跑的和队列中等待的)执行完;
2、或者 等超时时间到了(timeout 和 TimeUnit设定的时间);
3、或者 线程被中断,抛出InterruptedException
然后会监测 ExecutorService 是否已经关闭,返回true(shutdown请求后所有任务执行完毕)或false(已超时)
boolean awaitTermination(long timeout, TimeUnit unit)throws InterruptedException;
示例如下:
public class ThreadPoolExecutorCloseTest {public static void main(String[] args) throws InterruptedException {ExecutorService executorService = new ThreadPoolExecutor(10,20,30,TimeUnit.SECONDS,new ArrayBlockingQueue<>(1),Thread::new,new ThreadPoolExecutor.AbortPolicy());IntStream.range(0, 20).boxed().forEach(i -> {executorService.execute(() -> {try {TimeUnit.SECONDS.sleep(10);System.out.println(Thread.currentThread().getName() + " [ " + i + " ] finish done.");} catch (InterruptedException e) {e.printStackTrace();}});});executorService.shutdown();/*** 当前线程阻塞,直到:* 1、等所有已提交的任务(包括正在跑的和队列中等待的)执行完* 2、或者 等超时时间到了(timeout 和 TimeUnit设定的时间)* 3、或者 线程被中断,抛出InterruptedException* 然后会监测 ExecutorService 是否已经关闭,返回true(shutdown请求后所有任务执行完毕)或false(已超时)*/boolean b = executorService.awaitTermination(30, TimeUnit.SECONDS);System.out.println(b);System.out.println("==============over==============");}
线程真正停止!
Thread-16 [ 17 ] finish done.
Thread-0 [ 0 ] finish done.
Thread-14 [ 15 ] finish done.
Thread-13 [ 14 ] finish done.
Thread-7 [ 7 ] finish done.
Thread-3 [ 3 ] finish done.
Thread-2 [ 2 ] finish done.
Thread-5 [ 5 ] finish done.
Thread-1 [ 1 ] finish done.
Thread-17 [ 18 ] finish done.
Thread-11 [ 12 ] finish done.
Thread-12 [ 13 ] finish done.
Thread-10 [ 11 ] finish done.
Thread-18 [ 19 ] finish done.
Thread-9 [ 9 ] finish done.
Thread-6 [ 6 ] finish done.
Thread-8 [ 8 ] finish done.
Thread-15 [ 16 ] finish done.
Thread-4 [ 4 ] finish done.
Thread-13 [ 10 ] finish done.
true
==============over==============Process finished with exit code 0
停止接收新任务,原来的任务停止执行
1、跟 shutdown() 一样,先停止接收新submit的任务;
2、忽略队列里等待的任务;
3、尝试将正在执行的任务interrupt中断;
4、返回未执行的任务列表 — new ArrayBlockingQueue<>(8)
说明:它试图终止线程的方法是通过调用 Thread.interrupt() 方法来实现的,这种方法的作用有限,如果线程中没有sleep 、wait、Condition、定时锁等应用, interrupt() 方法是无法中断当前的线程的。所以,shutdownNow() 并不代表线程池就一定立即就能退出,它也可能必须要等待所有正在执行的任务都执行完成了才能退出。但是大多数时候是能立即退出的。
public class ThreadPoolExecutorCloseTest {public static void main(String[] args) {ExecutorService executorService = new ThreadPoolExecutor(10,20,30,TimeUnit.SECONDS,new ArrayBlockingQueue<>(8),Thread::new,new ThreadPoolExecutor.AbortPolicy());IntStream.range(0, 20).boxed().forEach(i -> {executorService.execute(() -> {try {TimeUnit.SECONDS.sleep(10);System.out.println(Thread.currentThread().getName() + " [ " + i + " ] finish done.");} catch (InterruptedException e) {
// e.printStackTrace();}});});shutdownNow(executorService);System.out.println("==============over==============");}private static void shutdownNow(ExecutorService executorService) {List runnableList = Lists.newArrayList();try {runnableList = executorService.shutdownNow();} catch (Exception e) {e.printStackTrace();}System.out.println(runnableList.size());}
8
==============over==============Process finished with exit code 0
shutdown只是将线程池的状态设置为SHUTWDOWN状态,正在执行的任务会继续执行下去,没有被执行的则中断。
而shutdownNow则是将线程池的状态设置为STOP,正在执行的任务则被停止,没被执行任务的则返回。
shutdown | shutdownNow |
---|---|
shutdown调用的是advanceRunState(SHUTDOWN) | shutdownNow调用的是(STOP) |
shutdown调用的是中断空闲的Workers | shutdownNow调用的是中断所有的Workers |
shutdownNow会把所有任务队列中的任务取出来,返回一个任务列表 |
advanceRunState区别:
/*** 从运行的状态过渡到targetState* 如果当前已经大于了targetState,就什么都不做。*/private void advanceRunState(int targetState) {for (;;) {int c = ctl.get();if (runStateAtLeast(c, targetState) ||ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))break;}}
targetState参数的使用值只有两个:SHUTDOWN与STOP
SHUTDOWN值为0
STOP值为1<<29 = 2^29
假设传的参数是SHUTDOWN:
ctlOf(targetState, workerCountOf©) = workerCountOf© > 0,一般就是线程池的个数
假设传的参数是STOP: 2^29:
ctlOf(targetState, workerCountOf©) = 2^29 + 2 , 为STOP状态
package com.thread.excutor;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;public class ThreadPoolExecutorLongTimeTest {public static void main(String[] args) {ExecutorService executorService = new ThreadPoolExecutor(10,20,30,TimeUnit.SECONDS,new ArrayBlockingQueue<>(8),Thread::new,new ThreadPoolExecutor.AbortPolicy());IntStream.range(0, 10).boxed().forEach(item -> {executorService.submit(() -> {while (true) {}});});try {executorService.shutdown();executorService.awaitTermination(5, TimeUnit.SECONDS);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("===============over================");}
}
线程池一直活着,无法停止!
package com.thread.excutor;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;public class ThreadPoolExecutorLongTimeTest {public static void main(String[] args) {ExecutorService executorService = new ThreadPoolExecutor(10,20,30,TimeUnit.SECONDS,new ArrayBlockingQueue<>(8),target -> {Thread thread = new Thread(target);thread.setDaemon(true);return thread;},new ThreadPoolExecutor.AbortPolicy());IntStream.range(0, 10).boxed().forEach(item -> {executorService.submit(() -> {while (true) {}});});try {executorService.shutdown();executorService.awaitTermination(5, TimeUnit.SECONDS); // 最多的期待时间} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("===============over================");}
}
ok!设置守护线程的手段!