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


    出现问题:线程池就一直存在,程序停滞

    线程池使用时,如果没有使用shutdown()去停止时,线程池就一直存在,程序停滞。

    1. package runnable;
    2. import java.util.concurrent.ExecutorService;
    3. import java.util.concurrent.Executors;
    4. import java.util.concurrent.ThreadPoolExecutor;
    5. /**
    6. * ClassName ThreadPoolDemo5
    7. * description isTerminated方法使用
    8. *
    9. * @author : HMF
    10. * date: 2022/7/20 11:08
    11. **/
    12. class Runnable5 implements Runnable{
    13. @Override
    14. public void run() {
    15. for(int i=0;i<10000;i++){
    16. if(i==999){
    17. System.out.println(Thread.currentThread().getName()+",线程在执行:"+i);
    18. }
    19. }
    20. }
    21. }
    22. public class ThreadPoolDemo5 {
    23. public static void main(String[] args) {
    24. //创建Runnable 对象
    25. Runnable5 rt = new Runnable5();
    26. int ThreadNum=10;
    27. ExecutorService exs = Executors.newFixedThreadPool(ThreadNum);
    28. for(int i=0;i
    29. exs.execute(rt);
    30. }
    31. }
    32. }

    执行结果:

     解决方法:shutdown()停止,isTerminated()判断是否结束

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

    具体方法:

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

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

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

    1. exs.shutdown();
    2. Runnable5 rt2 = new Runnable5();
    3. exs.execute(rt2);

    •  isTerminated() 判断方式,在执行 shutdown() ,关闭线程池后,判断是否所有任务已经完成。

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

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

    1. package runnable;
    2. import java.util.concurrent.ExecutorService;
    3. import java.util.concurrent.Executors;
    4. /**
    5. * ClassName ThreadPoolDemo5
    6. * description isTerminated方法使用
    7. *
    8. * @author : HMF
    9. * date: 2022/7/20 11:08
    10. **/
    11. class Runnable5 implements Runnable{
    12. @Override
    13. public void run() {
    14. for(int i=0;i<10000;i++){
    15. if(i==999){
    16. System.out.println(Thread.currentThread().getName()+",线程在执行:"+i);
    17. }
    18. }
    19. }
    20. }
    21. public class ThreadPoolDemo5 {
    22. public static void main(String[] args) {
    23. //创建Runnable 对象
    24. Runnable5 rt = new Runnable5();
    25. int ThreadNum=10;
    26. ExecutorService exs = Executors.newFixedThreadPool(ThreadNum);
    27. for(int i=0;i
    28. exs.execute(rt);
    29. }
    30. exs.shutdown();
    31. isTerminated(exs,1);
    32. }
    33. public static void isTerminated(ExecutorService exs,int time){
    34. if(!exs.isTerminated()){
    35. try {
    36. System.out.println("线程池结束状态:"+exs.isTerminated());
    37. Thread.sleep(time);
    38. isTerminated(exs,time);
    39. }
    40. catch (Exception e){
    41. System.out.println(e);
    42. }
    43. }else {
    44. System.out.println("线程池结束状态::"+exs.isTerminated());
    45. }
    46. }
    47. }

    执行结果:

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

  • 相关阅读:
    卷积神经网络大致结构、卷积层设计的参数、卷积结果计算公式、卷积参数的共享、池化层、卷积神经网络的具体结构、感受野、推荐使用的卷积神经网络
    通信算法之八十:信道均衡-MMSE 定点化
    如何在做gpt2中文模型搭建时出现以下bug?
    工业智能网关BL110应用之五十三: 实现西门子S7-200 PLC接入OPC UA 云平台
    Docker 部署 Geoserver
    我们这样的人
    python操作windows桌面实现鼠标、键盘操作,python之pyautogui库文档详解
    【JS】react antd 项目如何让Table组件表格滚动播放
    Android学习笔记 50. Android 多媒体技术——SoundPool播放音效
    C++ 语言学习 day07 函数异常,模板,模板类
  • 原文地址:https://blog.csdn.net/fen_fen/article/details/125888813