ShutDown和ShutDownNow的区别

在多线程编程中,经常会遇到将线程池关闭的case。这就会使用到ShutDown和ShutDownNow,这两者到底适合哪种使用场景呢?

个人对其进行了一番测试:

场景一:所有线程都是一个task,都是批处理作业,相互之间没有什么关系,某个线程的异常对结果影响不大。那么所有线程都能在执行任务结束之后可以正常结束,程序能在所有task都做完之后正常退出,适合用ShutDown。

场景二:所有线程都是一个工人,源源不断的从任务池中接收任务,整个任务周期非常长。但是,如果一个线程在做某个任务的时候失败,则整个结果就是失败的,其他worker再继续做剩下的任务也是徒劳,这就需要让他们全部停止当前的工作。这里使用ShutDownNow就可以让该pool中的所有线程都停止当前的工作,从而迫使所有线程执行退出。从而让主程序正常退出。

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

public class TestShutDown {
    public static void main(String[] args) {
        try {
            testShutDown(100);
            testShutDowNow(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void testShutDown(int startNo) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 5; i++) {
            executorService.execute(getTask(i + startNo));
        }
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.DAYS);
        System.out.println("shutDown->all thread shutdown");
    }

    public static void testShutDowNow(int startNo) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 5; i++) {
            executorService.execute(getTask(i + startNo));
        }
        executorService.shutdownNow();
        executorService.awaitTermination(1, TimeUnit.DAYS);
        System.out.println("shutdownNow->all thread shutdown");
    }

    public static Runnable getTask(int threadNo) {
        final Random rand = new Random();
        final int no = threadNo;
        Runnable task = new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(no + "-->" + rand.nextInt(10));
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println("thread " + no + " has error" + e);
                }
            }
        };
        return task;
    }
}

执行结果:

shutDown后可以使用awaitTermination等待所有线程执行完毕当前任务。

shutDownNow就会迫使当前执行的所有任务停止工作。

100-->2
101-->9
102-->0
103-->0
104-->9
shutDown->all thread shutdown
200-->9
201-->8
thread 200 has errorjava.lang.InterruptedException: sleep interrupted
thread 201 has errorjava.lang.InterruptedException: sleep interrupted
shutdownNow->all thread shutdown
时间: 2024-08-25 06:23:33

ShutDown和ShutDownNow的区别的相关文章

ExecutorService对象的shutdown 和shutdownNow 的区别

可以关闭 ExecutorService,这将导致其拒绝新任务.提供两个方法来关闭 ExecutorService.shutdown() 方法在终止前允许执行以前提交的任务,而 shutdownNow() 方法阻止等待任务启动并试图停止当前正在执行的任务.在终止时,执行程序没有任务在执行,也没有任务在等待执行,并且无法提交新任务.应该关闭未使用的 ExecutorService 以允许回收其资源. 下列方法分两个阶段关闭 ExecutorService.第一阶段调用 shutdown 拒绝传入任

原 线程池中shutdown()和shutdownNow()方法的区别

参考:shutdown和shutdownNow的区别 shutDown() 当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态.此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionException异常.但是,此时线程池不会立刻退出,直到添加到线程池中的任务都已经处理完成,才会退出. shutdownNow() 根据JDK文档描述,大致意思是:执行该方法,线程池的状态立刻变成STOP状态,并试图停止所有正在执行的线程,不再处理还在池队列中等待的任务,

shutdown和close的区别

[shutdown和close的区别] 当所有的数据操作结束以后,你可以调用close()函数来释放该socket,从而停止在该socket上的任何数据操作:close(sockfd); 你也可以调用shutdown()函数来关闭该socket.该函数允许你只停止在某个方向上的数据传输,而一个方向上的数据传输继续进行.如你可以关 闭某socket的写操作而允许继续在该socket上接受数据,直至读入所有数据. int shutdown(int sockfd,int how); Sockfd是需要

init shutdown reboot poweroff halt区别

init 首先看看LINUX系统几种运行级别# 0 - 停机(千万别把initdefault设置为0,否则系统永远无法启动)# 1 - 单用户模式# 2 - 多用户,没有 NFS# 3 - 完全多用户模式(标准的运行级)# 4 – 系统保留的# 5 - X11 (x window)# 6 - 重新启动 (千万不要把initdefault 设置为6,否则将一直在重启 ) #init 0 切换到运行级别0动作为运行如下两个脚本: [[email protected] rc0.d]# pwd /etc

Java线程池应用

Executors工具类用于创建Java线程池和定时器. newFixedThreadPool:创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程.在任意点,在大多数 nThreads 线程会处于处理任务的活动状态.如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待.如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要).在某个线程被显式地关闭之前,池中的线程将一直存在. 创建一个固定大小的线程池来执

J.U.C ThreadPoolExecutor解析

Java里面线程池顶级接口是Executor,但严格意义上讲Executor并不是一个线程池,而是一个线程执行工具,真正的线程池接口是ExecutorService.关系类图如下: 首先Executor的execute方法只是执行一个Runnable任务而已,当然从某种角度上讲最后的实现类也是在线程中启动该任务. void execute(Runnable command); ExecutorService在Executor的基础上增加了一些任务提交方法: <T> Future<T>

Android性能优化之使用线程池处理异步任务

说到线程,我想大家都不陌生,因为在开发时候或多或少都会用到线程,而通常创建线程有两种方式: 1.继承Thread类 2.实现Runnable接口 虽说这两种方式都可以创建出一个线程,不过它们之间还是有一点区别的,主要区别在于在多线程访问同一资源的情况下,用Runnable接口创建的线程可以处理同一资源,而用Thread类创建的线程则各自独立处理,各自拥有自己的资源. 所以,在Java中大多数多线程程序都是通过实现Runnable来完成的,而对于Android来说也不例外,当涉及到需要开启线程去完

Android 性能优化之使用线程池处理异步任务

说到线程,我想大家都不陌生,因为在开发时候或多或少都会用到线程,而通常创建线程有两种方式: 1.继承Thread类 2.实现Runnable接口 虽说这两种方式都可以创建出一个线程,不过它们之间还是有一点区别的,主要区别在于在多线程访问同一资源的情况下,用Runnable接口创建的线程可以处理同一资源,而用Thread类创建的线程则各自独立处理,各自拥有自己的资源. 所以,在Java中大多数多线程程序都是通过实现Runnable来完成的,而对于Android来说也不例外,当涉及到需要开启线程去完

520特篇-爱的境界

本文的主旨在于通过对实际生活中爱情的例子做抽象来说明热爱能够对学习技术起到的作用及所能达到的程度.文章后半部分用具体项目做例子一来介绍实用的知识点二来说明主题.谨以此篇献给热爱工作热爱技术的你. 老公当初刚和我在一起的时候,很多人跑来问我要不要考虑和他们在一起.因为当时我在东软是不管什么事情只要参加,大奖肯定是我的.内部期刊上经常是我的身影.东软商用那年人特别多,大概快2万人了.日语考试我都是考第一的,甩出第二名好多分.所以很多人觉得优秀的人应该和在他们眼里优秀的人在一起.对于他们我只是笑笑,心