Java并发编程系列32:线程池shutdown()和exs.isTerminated()结合使用

  • Post author:
  • Post category:java


出现问题:

线程池就一直存在,程序停滞

线程池使用时,如果没有使用

shutdown()去停止时,线程池就一直存在,程序停滞。

package runnable;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * ClassName ThreadPoolDemo5
 * description isTerminated方法使用
 *
 * @author : HMF
 * date: 2022/7/20 11:08
 **/

class Runnable5 implements Runnable{

    @Override
    public void run() {
        for(int i=0;i<10000;i++){
            if(i==999){
                System.out.println(Thread.currentThread().getName()+",线程在执行:"+i);
            }
        }
    }
}

public class ThreadPoolDemo5 {
    public static  void main(String[] args) {
        //创建Runnable 对象
        Runnable5 rt = new Runnable5();
        int ThreadNum=10;
        ExecutorService exs = Executors.newFixedThreadPool(ThreadNum);
        for(int i=0;i<ThreadNum;i++){
            exs.execute(rt);
        }

    }
}

执行结果:


解决方法:

shutdown()停止,

isTerminated()判断是否结束

多线程中使用线程池,例如:newFixedThreadPool 等4种线程池或自定义线程池时,需要使用停止线程,并需要判断是否线程池是否停止。


具体方法:

  • shutdown(),它可以安全地关闭一个线程池

调用 shutdown() 方法之后线程池并不是立刻就被关闭,因为这时线程池中可能还有很多任务正在被执行,或是任务队列中有大量正在等待被执行的任务,


调用 shutdown() 方法后线程池会在执行完正在执行的任务和队列中等待的任务后才彻底关闭。

调用 shutdown() 方法后如果还有新的任务被提交,线程池则会根据拒绝策略直接拒绝后续新提交的任务。

        exs.shutdown();
        Runnable5 rt2 = new Runnable5();
        exs.execute(rt2);


  • isTerminated()

    判断方式,在执行

    shutdown()

    ,关闭线程池后,判断是否所有任务已经完成。

    这个方法可以检测线程池是否真正“终结”了,这不仅代表线程池已关闭,同时代表线程池中的所有任务都已经都执行完毕了。

    直到所有任务都执行完毕了,调用 isTerminated() 方法才会返回 true,这表示线程池已关闭并且线程池内部是空的,所有剩余的任务都执行完毕了。

package runnable;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * ClassName ThreadPoolDemo5
 * description isTerminated方法使用
 *
 * @author : HMF
 * date: 2022/7/20 11:08
 **/

class Runnable5 implements Runnable{

    @Override
    public void run() {
        for(int i=0;i<10000;i++){
            if(i==999){
                System.out.println(Thread.currentThread().getName()+",线程在执行:"+i);
            }
        }
    }
}



public class ThreadPoolDemo5 {
    public static  void main(String[] args) {
        //创建Runnable 对象
        Runnable5 rt = new Runnable5();
        int ThreadNum=10;
        ExecutorService exs = Executors.newFixedThreadPool(ThreadNum);
        for(int i=0;i<ThreadNum;i++){
            exs.execute(rt);
        }

        exs.shutdown();
        isTerminated(exs,1);
    }


    public static void isTerminated(ExecutorService exs,int time){
        if(!exs.isTerminated()){
            try {
                System.out.println("线程池结束状态:"+exs.isTerminated());
                Thread.sleep(time);
                isTerminated(exs,time);
            }
            catch (Exception e){
                System.out.println(e);
            }
        }else {
            System.out.println("线程池结束状态::"+exs.isTerminated());
        }
    }
}

执行结果:

第一次判断线程池如果未结束,休眠1秒钟再去判断(循环判断),知道线程池结束。



版权声明:本文为fen_fen原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。