美文网首页
停止线程池的正确方法

停止线程池的正确方法

作者: wbpailxt | 来源:发表于2021-04-15 17:14 被阅读0次

    shutdown()方法仅仅是关闭线程池的队列入口

    package threadpool;
    
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 描述:     演示关闭线程池
     */
    public class ShutDown {
    
        public static void main(String[] args) throws InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            for (int i = 0; i < 100; i++) {
                executorService.execute(new ShutDownTask());
            }
            Thread.sleep(1500);
    
            System.out.println("演示关闭队列入口之后不再允许提交任务到队列");
            System.out.println("关闭线程池之前isShutdown的值:" + executorService.isShutdown());
            executorService.shutdown();
            System.out.println("关闭线程池之后isShutdown的值:" + executorService.isShutdown());
            executorService.execute(new ShutDownTask());
        }
    }
    
    class ShutDownTask implements Runnable {
        @Override
        public void run() {
            try {
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + "被中断了");
            }
        }
    }
    

    1、shutdown()代表关闭线程池队列入口,那么isShutdown()判断的就是线程池队列入口有没关闭。
    2、线程池队列入口关闭之后还继续往线程池添加任务则会抛出RejectedExecutionException异常。

    isTerminated()是判断线程池是否停止

    停止:线程池队列入口关闭且线程池中任务都执行完毕

    package threadpool;
    
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 描述:     演示关闭线程池
     */
    public class ShutDown {
    
        public static void main(String[] args) throws InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            for (int i = 0; i < 100; i++) {
                executorService.execute(new ShutDownTask());
            }
            Thread.sleep(1500);
    
            System.out.println("演示主线程等待10s之后,看线程池的isTerminated的值");
            executorService.shutdown();// 需要注意,线程池不调用shutdown方法是不能关闭的,那么isTerminated一直是false,且该程序也不能关闭
            Thread.sleep(10000);
            System.out.println("线程等待10s之后isTerminated的值:" + executorService.isTerminated());
        }
    }
    
    class ShutDownTask implements Runnable {
        @Override
        public void run() {
            try {
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + "被中断了");
            }
        }
    }
    
    执行结果

    1、如果没有关闭线程池队列入口,那么线程池isTerminated永远为false,不管线程池中任务是否都执行完毕

    awaitTermination等待一段时间,检查线程池isTerminated()

    package threadpool;
    
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 描述:     演示关闭线程池
     */
    public class ShutDown {
    
        public static void main(String[] args) throws InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            for (int i = 0; i < 100; i++) {
                executorService.execute(new ShutDownTask());
            }
            Thread.sleep(1500);
    
            System.out.println("演示线程池等待n秒之后");
            executorService.shutdown();// 需要注意,线程池不调用shutdown方法是不能关闭的,也就是awaitTermination无论等待多久都是false,且该程序也不能关闭
            boolean b = executorService.awaitTermination(7L, TimeUnit.SECONDS);
            System.out.println("线程池等待n秒之后,awaitTermination返回的值" + b) ;
        }
    }
    
    class ShutDownTask implements Runnable {
        @Override
        public void run() {
            try {
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + "被中断了");
            }
        }
    }
    
    执行结果

    1、既然是判断线程池是否停止,那么同第二个例子一样,在执行awaitTermination方法之前需要执行shutdown()方法。

    shutdownNow()方法会中断正在执行的线程,并且关闭队列入口和将队列中的任务返回

    package threadpool;
    
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 描述:     演示关闭线程池
     */
    public class ShutDown {
    
        public static void main(String[] args) throws InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            for (int i = 0; i < 100; i++) {
                executorService.execute(new ShutDownTask());
            }
            Thread.sleep(1500);
    
            System.out.println("演示shutdownNow()方法会中断正在执行的线程,并且将队列中的任务返回");
            List<Runnable> runnableList = executorService.shutdownNow();
            System.out.println(runnableList);
            System.out.println("shutdownNow之后线程池isShutdown的值" + executorService.isShutdown());
            System.out.println("shutdownNow之后线程池isTerminated的值" + executorService.isTerminated());
        }
    }
    
    class ShutDownTask implements Runnable {
        @Override
        public void run() {
            try {
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + "被中断了");
            }
        }
    }
    
    执行结果

    1、shutdownNow()方法既关闭线程池队列入口,还”强迫“线程池中任务立刻完成(即中断)。

    相关文章

      网友评论

          本文标题:停止线程池的正确方法

          本文链接:https://www.haomeiwen.com/subject/ifmclltx.html