shutdown():
把線程池的狀態設置成SHUTDOWN狀態,然後中斷所有沒有正執行任務的線程
shutdownNow():
首先把線程池的狀態設置成STOP,然後嘗試停止所有正在執行任務或者暫停任務的線程,並返回等待執行任務的列表
常用
通常我們調用shutdown()方法關閉線程池,如果不需要任務執行完成,可以調用shutdownNow()
原理
遍歷線程池中的工作線程,然後組個調用線程的interrupt方法來中斷線程,所以無法響應中斷任務的可能永遠無法停止
其他方法
isShutdown():
只要調用了shutdown或者shutdownNow,isShutdown就會返回true,否則false
isTerminaed():
當所有任務關閉之後,才表示線程池關閉成功,這時會返回true
isTerminating:
執行了shutdown或shutdownNow之後,還有任務正在進行中=true,沒有任務進行中=false
測試示例
測試shutdown
public class Test {
static class Customer extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "開始執行");
try {
//模擬任務執行4s
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "執行完成");
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10,
20,
20,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
//1、設置線程的名字
Thread thread = new Thread(r);
//thread.setName("通過自定義線程工廠誰知線程名字");
//2、設置成守護線程
//thread.setDaemon(true);
return thread;
}
},
//四種阻塞隊列滿之後的處理方式
// new ThreadPoolExecutor.CallerRunsPolicy()); 使用調用線程處理,比如是main調用的線程池,用main線程執行
// new ThreadPoolExecutor.DiscardOldestPolicy());把阻塞隊列首元素丟掉,執行當前線程
// new ThreadPoolExecutor.DiscardPolicy());直接丟掉當前線程
new AbortPolicy());//跑出異常
executor.execute(new Customer());
Thread.sleep(100);
//當前線程還未執行完,執行shutdown
System.out.println("執行shutdown之前");
System.out.println(executor.isTerminated());
System.out.println(executor.isShutdown());
System.out.println(executor.isTerminating());
executor.shutdown();
System.out.println("執行shutdown之後,但是還有任務正在執行");
//線程還沒有執行完成,isTerminated()=false
System.out.println(executor.isTerminated());
System.out.println(executor.isShutdown());
System.out.println("有任務進行中isTerminating="+executor.isTerminating());
//線程執行完成,isTerminated()=true
Thread.sleep(4000);
System.out.println("執行shutdown之後,所有任務執行完成");
System.out.println(executor.isTerminated());
System.out.println("沒有任務進行中isTerminating="+executor.isTerminating());
}
}
結果
Thread-1開始執行
執行shutdown之前
false
false
false
執行shutdown之後,但是還有任務正在執行
false
true
有任務進行中isTerminating=true
Thread-1執行完成
執行shutdown之後,所有任務執行完成
true
沒有任務進行中isTerminating=false
測試shutdownNow
public class Test {
static class Customer extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "開始執行");
try {
//模擬任務執行4s
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "執行完成");
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10,
20,
20,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
//1、設置線程的名字
Thread thread = new Thread(r);
//thread.setName("通過自定義線程工廠誰知線程名字");
//2、設置成守護線程
//thread.setDaemon(true);
return thread;
}
},
//四種阻塞隊列滿之後的處理方式
// new ThreadPoolExecutor.CallerRunsPolicy()); 使用調用線程處理,比如是main調用的線程池,用main線程執行
// new ThreadPoolExecutor.DiscardOldestPolicy());把阻塞隊列首元素丟掉,執行當前線程
// new ThreadPoolExecutor.DiscardPolicy());直接丟掉當前線程
new AbortPolicy());//跑出異常
executor.execute(new Customer());
Thread.sleep(100);
//當前線程還未執行完,執行shutdown
System.out.println("執行shutdown之前");
System.out.println(executor.isTerminated());
System.out.println(executor.isShutdown());
System.out.println(executor.isTerminating());
executor.shutdownNow();
System.out.println("執行shutdown之後,但是還有任務正在執行");
//線程還沒有執行完成,isTerminated()=false
System.out.println(executor.isTerminated());
System.out.println(executor.isShutdown());
System.out.println("有任務進行中isTerminating="+executor.isTerminating());
//線程執行完成,isTerminated()=true
Thread.sleep(4000);
System.out.println("執行shutdown之後,所有任務執行完成");
System.out.println(executor.isTerminated());
System.out.println("沒有任務進行中isTerminating="+executor.isTerminating());
}
}
結果:因爲要中斷正在執行的任務,所有會報中斷異常
Thread-1開始執行
執行shutdown之前
false
false
false
執行shutdown之後,但是還有任務正在執行
false
true
有任務進行中isTerminating=true
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at cn.enjoyedu.ch6.Test$Customer.run(Test.java:14)
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:748)
Thread-1執行完成
執行shutdown之後,所有任務執行完成
true
沒有任務進行中isTerminating=false