1.shutdown()方法:
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.Invocation has no additional effect if already shut down.(启动有序关闭,在该关闭中执行先前提交的任务,但不接受任何新任务。如果已关闭,则调用不会产生任何其他影响。)
(1).不使用shutdown()方法
public class TestShutdown {
public static void main(String[] args) {
MyRunnable1 myRunnable1 =new MyRunnable1();
ThreadPoolExecutor executor = new ThreadPoolExecutor(7,10,0L, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>());
executor.execute(myRunnable1);
System.out.println("main end....");
}
}
class MyRunnable1 implements Runnable{
@Override
public void run() {
try{
System.out.println("begin:"+Thread.currentThread().getName());
Thread.sleep(4000);
System.out.println("end:"+Thread.currentThread().getName());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
运行结果:
如图线程池执行完成任务以后,线程池不关闭,继续等待新的任务。
(2).使用shutdown()方法
package com.springboot.thread;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestShutdown {
public static void main(String[] args) {
MyRunnable1 myRunnable1 =new MyRunnable1();
ThreadPoolExecutor executor = new ThreadPoolExecutor(7,10,0L, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>());
executor.execute(myRunnable1);
System.out.println("main end....");
executor.shutdown();
}
}
class MyRunnable1 implements Runnable{
@Override
public void run() {
try{
System.out.println("begin:"+Thread.currentThread().getName());
Thread.sleep(4000);
System.out.println("end:"+Thread.currentThread().getName());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
运行结果:
如图使用shutdown()方法以后,线程池中的线程将任务完成以后线程池自动关闭。
(3).在shutdown()方法以后向线程池中添加新的任务
package com.springboot.thread;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestShutdown {
public static void main(String[] args) {
MyRunnable1 myRunnable1 =new MyRunnable1();
ThreadPoolExecutor executor = new ThreadPoolExecutor(7,10,0L, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>());
executor.execute(myRunnable1);
System.out.println("main end....");
executor.shutdown();
executor.execute(myRunnable1);
}
}
class MyRunnable1 implements Runnable{
@Override
public void run() {
try{
System.out.println("begin:"+Thread.currentThread().getName());
Thread.sleep(4000);
System.out.println("end:"+Thread.currentThread().getName());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
运行结果:
如图,我们可以看出在线程池中的线程将任务执行完成以后,main线程抛出java.util.concurrent.RejectedExecutionException 。
正如shutdown()方法说明的那样,将已经加入的线程池中的任务执行完毕后不再添加新的任务。
2.shutdownNow()方法 :Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution. These tasks are drained (removed) from the task queue upon return from this method.(尝试停止所有正在执行的任务,暂停正在等待的任务的处理,并返回正在等待执行的任务的列表。 此方法返回后,这些任务将从任务队列中耗尽(删除)。)
源码:
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(STOP);
interruptWorkers();
tasks = drainQueue();
} finally {
mainLock.unlock();
}
tryTerminate();
return tasks;
}
上面的解释虽然比较精简但是可能比较难以理解,在《java并发编程核心方法与核心框架》中给出了更好的解释,如下:shutdownNow ()的作用是中断所有的任务Task,并且抛出InterruptedException异常,前提是在Runnable中使用了if(Thread.currentThread().isInterrupted()=true)来判断当前线程的中断状态,而未执行的线程不再执行,也就是从任务队列中清除。如果没有使用if(Thread.currentThread().isInterrupted()=true)语句及抛出异常的代码,则池中正在运行的线程直到运行完毕,而未执行的线程也不再执行,也从任务队列中清除。
总结下来就是:如果使用if(Thread.currentThread().isInterrupted()=true)来判断当前线程的中断状态并且抛出线程中断异常那么线程池中正在执行的任务被中断,如果没使用用if(Thread.currentThread().isInterrupted()=true)来判断当前线程的中断状态,并且没有抛出异常的话,正在执行的线程继续执行完,但只要你使用了shutdownNow ()方法那么所有等待执行的线程全部都会被清除。
使用 if (Thread.currentThread().isInterrupted() == true)并抛出线程被中断的异常的代码如下:
package com.springboot.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ShutdownNowTest {
public static void main(String[] args) throws InterruptedException {
ShutdownRunable1 shutdownRunable1 = new ShutdownRunable1();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,9999,9999, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>());
threadPoolExecutor.execute(shutdownRunable1);
threadPoolExecutor.execute(shutdownRunable1);
threadPoolExecutor.execute(shutdownRunable1);
threadPoolExecutor.execute(shutdownRunable1);
Thread.sleep(1000);
threadPoolExecutor.shutdownNow();
}
}
class ShutdownRunable1 implements Runnable {
@Override
public void run() {
try {
/*耗时操作*/
for (int i = 0; i <= Integer.MAX_VALUE / 50; i++) {
Math.random();
Math.random();
Math.random();
Math.random();
Math.random();
if (Thread.currentThread().isInterrupted() == true) {
System.out.println("任务没有完成就中断了!");
throw new InterruptedException();
}
}
System.out.println("任务完成了!");
} catch (InterruptedException e) {
System.out.println("进入catch中,中断了任务!");
e.printStackTrace();
}
}
}
运行结果:
任务没有完成就中断了!
任务没有完成就中断了!
进入catch中,中断了任务!
进入catch中,中断了任务!
java.lang.InterruptedException
at com.springboot.thread.ShutdownRunable1.run(ShutdownNowTest.java:35)
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
at com.springboot.thread.ShutdownRunable1.run(ShutdownNowTest.java:35)
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)
不使用if (Thread.currentThread().isInterrupted() == true)并抛出线程被中断的异常的代码如下:
package com.springboot.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ShutdownNowTest {
public static void main(String[] args) throws InterruptedException {
ShutdownRunable1 shutdownRunable1 = new ShutdownRunable1();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,9999,9999, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>());
threadPoolExecutor.execute(shutdownRunable1);
threadPoolExecutor.execute(shutdownRunable1);
threadPoolExecutor.execute(shutdownRunable1);
threadPoolExecutor.execute(shutdownRunable1);
Thread.sleep(1000);
threadPoolExecutor.shutdownNow();
}
}
class ShutdownRunable1 implements Runnable {
@Override
public void run() {
/*try {*/
/*耗时操作*/
for (int i = 0; i <= Integer.MAX_VALUE / 50; i++) {
Math.random();
Math.random();
Math.random();
Math.random();
Math.random();
/* if (Thread.currentThread().isInterrupted() == true) {
System.out.println("任务没有完成就中断了!");
throw new InterruptedException();
}*/
}
System.out.println("任务完成了!");
/* } catch (InterruptedException e) {
System.out.println("进入catch中,中断了任务!");
e.printStackTrace();
}*/
}
}
运行结果:
3.isShutdown()方法:此方法的作用是判断线程池是否已经关闭。
package com.springboot.thread;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestIsShutdown {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("begin:"+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end:"+Thread.currentThread().getName());
}
};
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,1000,1000L, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>());
threadPoolExecutor.execute(runnable);
System.out.println(threadPoolExecutor.isShutdown());
threadPoolExecutor.shutdown();
System.out.println(threadPoolExecutor.isShutdown());
}
}
运行结果:
false
true
begin:pool-1-thread-1
end:pool-1-thread-1