1.shutdownNow
shutdownNow和shutdown的最主要的区别是:shutdown会等待所有提交的任务执行完成,不管是正在执行还是保存在任务队列中的已提交任务。而shutdownNow会尝试中断正在执行的任务(其主要是中断一些指定方法如sleep方法),并且停止执行等待队列中提交的任务。
中断Sleep任务
package com.cweeyii.threadpool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created by wenyi on 16/10/16.
* Email:caowenyi@meituan.com
*/
public class SleepWorker implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(SleepWorker.class);
private String workerName;
public String getWorkerName() {
return workerName;
}
public void setWorkerName(String workerName) {
this.workerName = workerName;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("threadName={} 线程结束{}工作", threadName,workerName);
}
}
package com.cweeyii.threadpool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.concurrent.*;
/**
* Created by wenyi on 16/10/16.
* Email:caowenyi@meituan.com
*/
public class ShutDownNowSleep {
private static final Logger LOGGER = LoggerFactory.getLogger(ShutDownNowSleep.class);
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
int workerNum = 2;
ExecutorService executorService = Executors.newFixedThreadPool(workerNum);
for (int i = 0; i < workerNum*3; i++) {
SleepWorker worker=new SleepWorker();
worker.setWorkerName("worker" + i);
executorService.submit(worker);
}
List<Runnable> workerList=executorService.shutdownNow();
executorService.awaitTermination(10, TimeUnit.SECONDS);
LOGGER.info("调用shutdown会立即返回不会等待线程池任务执行完");
for(Runnable woker:workerList){
FutureTask<SleepWorker> futureTask=(FutureTask<SleepWorker>)woker;
futureTask.run();
}
}
}
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.cweeyii.threadpool.SleepWorker.run(SleepWorker.java:27)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.cweeyii.threadpool.SleepWorker.run(SleepWorker.java:27)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
11:45:17.513 INFO (SleepWorker.java:31) - threadName=pool-1-thread-2 线程结束worker1工作
11:45:17.513 INFO (SleepWorker.java:31) - threadName=pool-1-thread-1 线程结束worker0工作
11:45:17.516 INFO (ShutDownNowSleep.java:26) - 调用shutdown会立即返回不会等待线程池任务执行完
11:45:19.521 INFO (SleepWorker.java:31) - threadName=main 线程结束worker2工作
11:45:21.525 INFO (SleepWorker.java:31) - threadName=main 线程结束worker3工作
11:45:23.526 INFO (SleepWorker.java:31) - threadName=main 线程结束worker4工作
11:45:25.527 INFO (SleepWorker.java:31) - threadName=main 线程结束worker5工作
忽略等待的任务
package com.cweeyii.threadpool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.concurrent.*;
/**
* Created by wenyi on 16/10/16.
* Email:caowenyi@meituan.com
*/
public class ShutDownNowBusy {
private static final Logger LOGGER = LoggerFactory.getLogger(ShutDownNowBusy.class);
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
int workerNum = 2;
ExecutorService executorService = Executors.newFixedThreadPool(workerNum);
for (int i = 0; i < workerNum*3; i++) {
BusyWorker worker=new BusyWorker();
worker.setWorkerName("worker" + i);
executorService.submit(worker);
}
List<Runnable> workerList=executorService.shutdownNow();
executorService.awaitTermination(10, TimeUnit.SECONDS);
LOGGER.info("调用shutdown会立即返回不会等待线程池任务执行完");
for(Runnable woker:workerList){
FutureTask<BusyWorker> futureTask=(FutureTask<BusyWorker>)woker;
futureTask.run();
}
}
}
package com.cweeyii.threadpool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created by wenyi on 16/10/16.
* Email:caowenyi@meituan.com
*/
public class BusyWorker implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(BusyWorker.class);
private String workerName;
public String getWorkerName() {
return workerName;
}
public void setWorkerName(String workerName) {
this.workerName = workerName;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
try {
busyMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("threadName={} 线程结束{}工作", threadName,workerName);
}
private void busyMethod() throws InterruptedException{
int k=0;
for(long i=0;i<100000L;i++){
for(long j=0;j<100000L;j++)
k++;
}
}
}
11:47:15.086 INFO (BusyWorker.java:31) - threadName=pool-1-thread-1 线程结束worker0工作
11:47:15.087 INFO (BusyWorker.java:31) - threadName=pool-1-thread-2 线程结束worker1工作
11:47:15.089 INFO (ShutDownNowBusy.java:26) - 调用shutdown会立即返回不会等待线程池任务执行完
11:47:19.354 INFO (BusyWorker.java:31) - threadName=main 线程结束worker2工作
11:47:23.123 INFO (BusyWorker.java:31) - threadName=main 线程结束worker3工作
11:47:26.912 INFO (BusyWorker.java:31) - threadName=main 线程结束worker4工作
11:47:30.907 INFO (BusyWorker.java:31) - threadName=main 线程结束worker5工作