精华内容
下载资源
问答
  • 关闭线程池的方法
    2022-07-17 17:39:22

    Q1:JVM退出时会不会关闭线程池?

    不会。JVM退出时会kill所有的进程内的线程。

    怎么优雅关闭线程池?

    shutdown方法将线程池状态从running->shutdown,这个状态下会拒绝所有提交的任务,直接调用拒绝策略。

    会尝试中断所有空闲线程。让剩余线程执行完当前任务并执行完队列中剩余任务。

    那shutdown什么时候推进状态呢?

    是在最后一个工作线程退出时会执行processWorkerExit,调用tryTerminate,先将状态推进到tyding,表示线程池正在清理中。

    其实这个tyding状态对线程池本身没什么逻辑执行,只是提供了terminated接口给用户去自定义逻辑做些清理事情。

    回调完terminated方法后再将tyding推进到terminated。此时所有工作线程消亡,队列也没有任务,线程池算是终结了。

    shutdownNow方法将状态从running->stop,此时中断所有线程无论是否空闲还是工作中,抽出队列所有任务待返回给用户。

    直接执行tryTerminate方法。

    JVM提供了钩子函数,在退出时回调这些钩子。在钩子中可以对线程池执行关闭。

    会开一个线程执行回调,并且等到钩子函数执行完毕JVM才会kill所有线程然后退出。

    对钩子函数要谨慎编程,否则造成JVM无法退出的情况。

    Runtime.getRuntime().addShutdownHook(new Thread() { // do something });

    参考文章:

    JVM关闭的时候到底会不会等待线程池线程任务执行完毕_wen-pan的博客-CSDN博客

    JVM关闭的时候到底会不会等待线程池线程任务执行完毕

    更多相关内容
  • 前言 相信大家在面试的时候经常会遇到「线程池」相关的问题,比如: ...如上这些问题,如果看过线程池源码的小伙伴,基本就能回答上来了,即便是看面试题也能说上个一二,但是当真的问你,如何关闭线程池?你能

    前言

    相信大家在面试的时候经常会遇到「线程池」相关的问题,比如:

    1. 什么是线程池?线程池的优点?
    2. 有哪几种创建线程池的方式?
    3. 四种创建线程池的使用场景?
    4. 线程池的底层原理?
    5. 线程池相关的参数,比如CorePoolSize、maximunPoolSize、keepAliveTime等等
    6. 为什么阿里巴巴不允许线程池使用Executors去创建?
    7. 如何合理的设置线程池参数的等等等等…

    如上这些问题,如果看过线程池源码的小伙伴,基本就能回答上来了,即便是看面试题也能说上个一二,但是当真的问你,如何关闭线程池?你能回答上来吗~

    其实这个问题直接关乎到你到底用没用过线程池,可以想象一下,当面试官问你用没用过线程池,如果你回答用过,还头头是道的说了一下如何如何创建,各个有哪些使用场景,底层有哪些参数等等,但此时问你,线程池如何关闭呢?两种关闭方法有什么区别呢?调用线程池关闭方法时线程池里的线程会有什么反应呢?

    这时,会不会很尴尬呢~,哦,会创建不会关闭呢。

    正文,文末总结

    今天我们不关心其他问题,就看如何关闭线程池,防止被面试官打个措手不及。

    关闭线程池有两个方法,分别是:shutdown()、shutdownNow()

    • shutdownNow():调用该方法后,首先将线程池的状态设置为 stop,线程池拒绝接受新任务的提交,然后尝试停止所有正在执行或者暂停任务的线程(也就是线程池里现有的任务也不再执行),并返回等待执行任务的列表。。
    • shutdown():调用该方法后,会将线程池的状态设置为 shutdown,线程池拒绝接受新任务的提交,同时等待线程池内的任务执行完毕之后再关闭线程池。

    看完这两个方法的解释,有一个小的结论:调用两个方法后都不会再接收新的任务,调用 shutdownNow() 会 “立刻” 停止线程池里所有的线程(注意,这里的立刻用的双引号,后面会否定这个立刻的),会返回等待执行的任务列表;调用 shutdown() 则会等待线程池里的任务执行完毕之后再关闭线程池,无返回值。

    无码无真相,我们通过代码去看看这两个方法(JDK1.8 + ThreadPoolExecutor):

    1、shutdownNow()
    public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();  1、检查线程,是否有权限修改
            advanceRunState(STOP);  2、修改线程池的状态为STOP状态
            interruptWorkers();     3、遍历线程池里的所有工作线程,然后调用线程的interrupt方法
            tasks = drainQueue();   4、将队列里还没有执行的任务放到列表里,返回给调用方
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }
    

    我们主要关注 try/catch 里的 4 行代码:

    1. checkShutdownAccess() :检查线程,是否有权限修改

    2. advanceRunState(STOP):修改线程池的状态为STOP状态

    3. interruptWorkers():遍历线程池里的所有工作线程,然后调用线程的interrupt方法

    4. drainQueue():将队列里还没有执行的任务放到列表里,返回给调用方

    这里我们额外看一下第三步 interruptWorkers() 方法,这可能是一些熟悉的东西:

    private void interruptWorkers() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers)
                w.interruptIfStarted();  这是这段代码的重点
        } finally {
            mainLock.unlock();
        }
    }
    

    可以看到一个 for 循环,然后调用 interruptIfStarted() 方法, 还是不熟悉怎么办?没关系的,我们接着往下看 interruptIfStarted() 方法:

    void interruptIfStarted() {
        Thread t;
        if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
            try {
                t.interrupt();  这是这段代码的重点
            } catch (SecurityException ignore) {
            }
        }
    }
    

    看到没,终究还是调的线程的 interrupt() 方法,不熟悉如何关闭线程的小伙伴可以移步这里 > 如何暂停一个正在运行的线程?

    先临时总结一下 shutdownNow() 方法的执行逻辑:将线程池状态修改为 STOP,然后遍历线程池里的工作线程,逐个调用线程的 interrupt() 方法来中断线程,因为是调用的 interrupt() 方法,所以线程并不会立刻执行结束,只是给线程设置了标志位,至于什么时候真的中断线程需要看 getTask() 方法的返回是否为 null 了(后面详看 getTask() 方法)。

    新的问题来了,我们再来看调用 shutdownNow() 方法后,线程池的线程会做如何反应,此时我们需要看一下线程池里的 runWorker() 方法,先给不太了解线程池运行过程的小伙伴补充一下流程:

    线程池调用execute提交任务 —> 创建Worker(设置属性thead、firstTask)—> worker.thread.start() —> 实际上调用的是 worker.run() —> 线程池的runWorker(worker) —> worker.firstTask.run()

    总之,运行线程池的就是在 runWorker() 方法里:

    final void runWorker(Worker w) {
      Thread wt = Thread.currentThread();
      Runnable task = w.firstTask;
      w.firstTask = null;
      w.unlock(); // allow interrupts
      boolean completedAbruptly = true; // 标志是不是用户任务异常导致终止的
      try {
          // 这里通过循环,不断地取任务来执行,getTask() 是会阻塞的
          while (task != null || (task = getTask()) != null) {
              w.lock();
              // stop 状态时不接受新任务,不执行已经加入任务队列的任务,还中断正在执行的任务
              // 所以对于 stop 状态以上是要中断线程的
              // (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP)确保线程中断标志位为true且是stop状态以上,接着清除了中断标志
              // !wt.isInterrupted()则再一次检查保证线程需要设置中断标志位
              if ((runStateAtLeast(ctl.get(), STOP) ||
                   (Thread.interrupted() &&
                    runStateAtLeast(ctl.get(), STOP))) &&
                  !wt.isInterrupted())
                  wt.interrupt();
              try {
                  beforeExecute(wt, task);// 回调方法,给子类具体实现
                  Throwable thrown = null;
                  try {
                      task.run(); // 执行我们提交给线程池的任务
                  } catch (RuntimeException x) {
                      thrown = x; throw x;
                  } catch (Error x) {
                      thrown = x; throw x;
                  } catch (Throwable x) {
                      thrown = x; throw new Error(x);
                  } finally {
                      afterExecute(task, thrown);//回调方法,给子类具体实现
                  }
              } finally {
                  task = null;// 置空,如果进入下一个循环可以继续取任务
                  w.completedTasks++;// 完成数+1
                  w.unlock();
              }
          }
          completedAbruptly = false;// 标记不是用户任务异常引起的
      } finally {
          processWorkerExit(w, completedAbruptly);
      }
    }
    

    正常情况下,线程池里的线程,通过 while 循环不停的执行任务,其中 task.run() 方法就是执行任务的关键代码,当我们调用了 shutdownNow() 方法时,task.run() 方法里面正处于IO阻塞时,则会导致报错,如果 task.run() 方法里正在正常执行,则不受影响,继续执行完这个任务。

    还有一种情况,getTask() 方法返回 null 时,也会导致线程的退出。

    private Runnable getTask() {
          boolean timedOut = false; // 取任务是否超时
          for (;;) {
              int c = ctl.get();
              int rs = runStateOf(c);
              // 这个状态判断挺重要的,起到线程池关闭作用
              if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                  decrementWorkerCount();// 线程数量减一
                  return null;// 这里返回null,意味着一个线程会退出
              }
              int wc = workerCountOf(c);
              // 这里可以看出核心线程在空闲的时候也是可以设置被回收的
              // timed为true将要有时间限制地取任务
              boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
    
              if ((wc > maximumPoolSize || (timed && timedOut))
                  && (wc > 1 || workQueue.isEmpty())) {
                  // 大于最大限制线程数或超过空闲时间,并且当前线程数大于1或队列为空
                  if (compareAndDecrementWorkerCount(c))
                      return null;// 说明线程数减一成功,返回null,意味着一个线程会退出
                  continue;// 上面线程数减一失败,说明线程数量已被抢先改变,继续循环,
              }
    
              try {
              		// 从队列中读取任务
                  Runnable r = timed ?
                      workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                      workQueue.take();
                  if (r != null)
                      return r;
                  timedOut = true;// 用于下一次循环中
              } catch (InterruptedException retry) {
                  timedOut = false;
              }
          }
      }
    

    这个 getTask() 过程就是,当我们调用 shutdownNow() 方法时,如果线程正处于从队列中读取任务( Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take(); )而发生阻塞,这样会导致抛出 InterruptedException 异常,但是这个异常被 try/catch 捕获掉了,同时设置了 timedOut 标志位,线程将会继续进入下一个 for 循环里继续执行。

    但因为 shutdownNow() 方法将线程状态设置为 STOP,所以当执行到下一个 for 循环的第一个 if语句 if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) 时,STOP 满足 >= SHUTDOWN,而 STOP 也满足 >= STOP,所以这个地方就尤为重要了,这个时候会进入 if 语句体中,返回 null ,然后线程退出。

    至此,总结一下,调用 shutdownNow() 方法时,程池里的线程会有什么反应?

    会有两种情况退出线程。

    当我们调用 shutdownNow() 方法时,如果线程池正在 getTask() 方法中执行,就会通过 for 循环进入 if 语句,判断条件是 标志位 >= SHUTDOWN,或者 标志位 >= STOP,因为符合条件所以会返回 null,然后线程退出。

    while (task != null || (task = getTask()) != null)

    再就是线程执行提交任务到线程池时而处于阻塞状态,就会导致报错抛出 InterruptedException 异常;处于正常运行状态下则会执行完当前任务,然后通过 getTask() 方法返回 null 来退出。

    2、shutdown()
    public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();     1、检查线程,是否有权限修改
            advanceRunState(SHUTDOWN); 2、修改线程池的状态为STOP状态
            interruptIdleWorkers();    3、遍历线程池里的所有工作线程,然后调用线程的interrupt方法
            onShutdown();              4、留给子类具体实现,如 ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
    }
    

    从上边 shutdownNow() 捋下来后,会发现 shutdown() 方法非常的相似:

    1. checkShutdownAccess():检查线程,是否有权限修改
    2. advanceRunState(SHUTDOWN):修改线程池的状态为STOP状态
    3. interruptIdleWorkers():遍历线程池里的所有工作线程,然后调用线程的interrupt方法
    4. onShutdown():留给子类具体实现,如 ScheduledThreadPoolExecutor

    具体方法细节就不重复了,大致过程就是:shutdown() 方法会修改线程状态为 SHUTDOWN 状态,然后调用 interruptIdleWorkers() 方法来中断空闲线程,这个过程也是同样的遍历线程池里的工作线程,逐个调用线程的 interrupt() 方法,至于什么时候真的中断线程需要看 getTask() 方法的返回是否为 null 了。

    然后就是:调用 shutdown() 方法时,程池里的线程会有什么反应?

    if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {

    在 getTask() 里的 if 判断中,由于线程池被 shutdown() 方法修改为 SHUTDOWN 状态,SHUTDOWN >= SHUTDOWN 条件成立,而逻辑且 & 的后半条件只有在队列为空,getTask() 方法才会返回 null,然后线程退出。

    最后总结

    关闭线程池有两种方法,分别是 shutdown()、shutdownNow(),调用两者都会让线程池不再接受新的任务,并且他们的原理都是遍历线程池中的工作线程,然后逐个调用线程的 inputter() 方法来中断线程,而两者的区别是,调用 shutdownNow() 会将线程池设置为 STOP 状态,该方法会返回等待执行的任务列表,而调用 shutdown() 方法会将线程池设置为 SHUTDOWN 状态,无返回值。

    调用了shutdown()、shutdown() 时,线程池里的线程会有什么反应?

    会有两种情况退出线程。

    1. 当我们调用关闭线程池方法时,如果线程池正在 getTask() 方法中执行,就会通过 for 循环进入 if 语句,判断线程池状态是否满足中断线程,如果满足就会返回 null,然后线程退出。

    2. 再就是线程执行提交任务到线程池时而处于阻塞状态时,就会导致报错抛出 InterruptedException 异常,线程退出;处于正常运行状态下则会执行完当前任务,然后通过 getTask() 方法返回 null 来退出。

    额外补充一:

    无论是 shutdownNow() 还是 shutdown(),由于原理都是调用单个线程的 interrupt() 方法,所以并不是直接就结束线程池的,而是通知线程池接下来的做法,但具体什么时间执行就不知道了,如何判断线程池真的关闭了可以调用 isTerminaed() 方法,返回 true 则表示关闭成功。

    额外补充二:

    如果需要同步等待线程池彻底关闭后才继续往下执行,需要调用 awaitTermination() 方法进行同步等待。其实实际开发过程中这种情景也是存在的,我在这举个简单的例子:

    组合文件下载,就是用户有2个及以上的文件下载需求,但是为了考虑用户体验,希望最终返回给用户的是一个压缩包文件(内嵌好几个小文件),所以为了快速首先是在后台采用了多线程的方式下载文件,然后用 awaitTermination() 方法同步等待,将最终的结果压缩为一个文件返回给用户。

    博客园持续更新,欢迎大家订阅关注,未来,我们一起成长。

    本文首发于博客园:https://www.cnblogs.com/niceyoo/p/13657538.html

    展开全文
  • ExecutorService的几种关闭线程池方法

    千次阅读 2016-03-31 15:48:39
    ExecutorService的几种关闭线程池方法: ExecutorService executorService =Executors.newFixedThreadPool(1); 1、shutdown()方法在终止前允许执行以前提交的任务。 这个方法会顺次地关闭ExecutorService,当...

    ExecutorService的几种关闭线程池方法:


    ExecutorService executorService =Executors.newFixedThreadPool(1);

    1、 shutdown()方法在终止前允许执行以前提交的任务。 这个方法会顺次地关闭ExecutorService,当我们调用这个方法时,ExecutorService停止接受任何新的任务且等待已经提交的任务执行完成(已经提交的任务会分两类:一类是已经在执行的,另一类是还没有开始执行的),当所有已经提交的任务执行完毕后将会关闭ExecutorService。

    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.

    This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.


     2、 shutdownNow()方法则是阻止正在任务队列中等待任务的启动并试图停止当前正在执行的任务,返回要停止的任务List。

     List<Runnable> 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.

    This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.

    There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt, so any task that fails to respond to interrupts may never terminate.

    Returns:
    list of tasks that never commenced execution

     3、awaitTermination方法:这个方法有两个参数,一个是timeout即超时时间,另一个是unit即时间单位。这个方法会使线程等待timeout时长,当超过timeout时间后,会监测ExecutorService是否已经关闭,若关闭则返回true,否则返回false。一般情况下会和shutdown方法组合使用。

    Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.

    Parameters:
    timeout the maximum time to wait
    unit the time unit of the timeout argument
    Returns:
    true if this executor terminated and false if the timeout elapsed before termination
    Throws:
    InterruptedException - if interrupted while waiting

    展开全文
  • 线程池关闭

    千次阅读 2021-10-21 10:03:12
    当我们调用线程的interrupt方法,它有两个作用: 如果此线程处于阻塞状态(比如调用了wait方法,io等待),则会立马退出阻塞,并抛出InterruptedException异常,线程就可以通过捕获InterruptedException来做一定的...

    1.线程中断

    当我们调用线程的interrupt方法,它有两个作用:

    1. 如果此线程处于阻塞状态(比如调用了wait方法,io等待),则会立马退出阻塞,并抛出InterruptedException异常,线程就可以通过捕获InterruptedException来做一定的处理,然后让线程退出。

    2. 如果此线程正处于运行之中,则线程不受任何影响,继续运行,仅仅是线程的中断标记被设置为true。所以线程要在适当的位置通过调用isInterrupted方法来查看自己是否被中断,并做退出操作。

    注:

    1. 如果线程的interrupt方法先被调用,然后线程调用阻塞方法进入阻塞状态,InterruptedException异常依旧会抛出。

    2. 如果线程捕获InterruptedException异常后,继续调用阻塞方法,将不再触发InterruptedException异常

    2.线程池的关闭

    线程池提供了两个关闭方法,shutdownNow和shuwdown方法。

    1. shutdownNow方法的解释是:线程池拒接收新提交的任务,同时立马关闭线程池,线程池里的任务不再执行。

    2. shutdown方法的解释是:线程池拒接收新提交的任务,同时等待线程池里的任务执行完毕后关闭线程池。

    2.1 shutdownNow

    1. 原子性的修改线程池的状态为stop
    2. 将队列里还没有执行的任务放到列表里,返回给调用方
    3. 遍历线程池里的所有工作线程,然后调用线程的interrupt方法。

    将线程池状态修改为STOP,然后调用线程池里的所有线程的interrupt方法。将还没有执行的任务 返回给 调用方

    正常情况下,线程池里的线程,就是在这个while循环里不停地执行。其中代码task.run()就是在执行我们提交给线程池的任务,如当我们调用shutdownNow时,task.run()里面正处于IO阻塞,则会导致报错,如果task.run()里正在正常执行,则不受影响,继续执行完这个任务。
    在这里插入图片描述

    2.2 shutdown

    跟shutdownNow类似,只不过它是将线程池的状态修改为SHUTDOWN状态,然后调用interruptIdleWorkers方法,来中断空闲的线程。

    跟shutdownNow方法调用interruptWorkers方法不同的是,interruptIdleWorkers方法在遍历线程池里的线程时,有一个w.tryLock()加锁判断,只有加锁成功的线程才会被调用interrupt方法。(就是正在执行线程池里任务的线程不会被中断)

    在这里插入图片描述

    3.优雅的关闭线程池

    有了上边对两个关闭线程池方法的了解,相信优雅安全关闭线程池将不再是问题。

    我们知道,使用shutdownNow方法,可能会引起报错,使用shutdown方法可能会导致线程关闭不了。

    所以当我们使用shutdownNow方法关闭线程池时,一定要对任务里进行异常捕获。

    当我们使用shuwdown方法关闭线程池时,一定要确保任务里不会有永久阻塞等待的逻辑,否则线程池就关闭不了。

    最后,一定要记得,shutdownNow和shuwdown调用完,线程池并不是立马就关闭了,要想等待线程池关闭,还需调用awaitTermination方法来阻塞等待。

    参考(其实就是复制):如何优雅的关闭线程池

    展开全文
  • ⾯试中经常会问到,创建⼀个线程池需要哪些参数、线程池的工作原理,却很少会问到线程池如何安全关闭的。也正是因为⼤家不是很关注这块,即便是⼯作三四年的⼈,也会有因为线程池关闭不合理,导致应用⽆法正常stop的...
  • 如何正确关闭线程池

    千次阅读 2020-04-10 23:46:29
    首先了解下ExecutorService接口中涉及线程池关闭的几个方法: /** *这个方法是一种安全关闭线程池方法,调用这个方法后, *线程池会根据拒绝策略来拒绝新提交的任务, *然后线程池会把正在执行的任务,和在...
  • 问题说明今天发现了一个问题,颠覆了我之前对关闭线程池的认识。一直以来,我坚信用shutdown + awaitTermination关闭线程池是最标准的方式。不过,这次遇到的问题是,子线程用到BufferedReader,而BufferedReader 的...
  • 如何优雅关闭线程池

    2022-01-03 12:34:59
    】如何优雅关闭线程池转载自:01 线程中断注:02 线程池关闭shutdownNow总结:shutdown总结:03 优雅的关闭线程池 转载自: ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠...
  • 线程池的三大方法

    2022-06-12 20:05:37
    线程池的三大方法
  • 【学习】线程池关闭线程池的shutdown方法
  • 创建线程池方法

    2020-11-10 18:36:56
    创建线程池方法 一、创建线程池的三种方法 Executors.newSingleThreadExecutor(); //单个线程 Executors.newFixedThreadPool(5); //创建一个固定的线程池 Executors.newCachedThreadPool(); //创建一个可伸缩的...
  • 我们经常在项目中使用的线程池,但是是否关心过线程池关闭呢,可能很多时候直接再项目中直接创建线程池让它一直运行当任务执行结束不在...在 Java 中和关闭线程池相关的方法主要有如下:void shutdown()List sh...
  • Java线程池关闭

    千次阅读 2021-07-12 17:17:03
    Java线程池关闭一、线程中断interrupt方法两个作用二、线程池关闭shutdownNow方法的源码:advanceRunState(STOP)interruptWorkers()tasks = drainQueue()runWorker方法源码getTask方法源码总结:shutdown方法的...
  • 调用这个方法线程池不会立即关闭,而是会等到所有线程执行完毕,还有 阻塞队列中的任务执行完毕后,再关闭。在此期间,线程池也会启用拒绝策略, 拒绝新的任务提交 */ threadPool.shutdown() /* 调用这个方法,...
  • 文章目录【ThreadPoolExecutor】关闭线程池一、源码分析1.1 线程池运行状态1.2 AtomicInteger 变量及相关操作1.3 shutdown() 及相关方法分析1.3.1 shutdown() 方法1.3.2 advanceRunState() 方法1.3.3 ...
  • shutdown(),它可以安全地关闭一个线程池,调用 shutdown() 方法之后线程池并不是立刻就被关闭,因为这时线程池中可能还有很多任务正在被执行,或是任务队列中有大量正在等待被执行的任务,调用 shutdown() 方法后...
  • newCachedThreadPool 这个一个带缓存的线程池,是个可以无限大的线程池,新建的线程放倒这个池子里,当线程停掉了的时候,下个个线程进来,可以复用这个线程。newFixedThreadPool 是个有长度的线程池,与上一个不同...
  • 对于一些定时任务或者网络请求服务将会使用线程池,当应用停机时需要正确安全的关闭线程池,如果处理不当,可能造成数据丢失,业务请求结果不正确等问题。关闭线程池我们可以选择什么都不做,JVM 关闭时自然的会清除...
  • 1.5 关闭线程池

    2021-11-28 21:05:38
    线程池中有很多关闭线程池方法,当业务需要的使用我们可以使用这些方法关闭线程。 shutdown 当调用线程池的shutdown方法时,线程中的任务并不会立刻停止,而是当调用shutdown方法后,线程池将不会接收新的任务,...
  • 首先看源码中的一句注释: A pool that is no longer ...如果程序中不再持有线程池的引用,并且线程池中没有线程时,线程池将会自动关闭线程池自动关闭的两个条件:1、线程池的引用不可达;2、线程池中没有...
  • 线程池的使用方法

    2020-12-30 16:10:43
    由于用了线程池没有关闭线程 导致生产上服务挂掉。好在没酿成大祸,生产上布了两台机器故障转移了。 1.使用线程池一定要shutdown() 如果不关程序一直会运行不停止每次调用都new新的线程池。直到内存不足new不出新...
  • 前面我们学习了常见线程池的创建及使用,但线程池在适时的时机关闭,本文我们来学习关闭线程池的几种方法。 涉及关闭线程池及状态检查的方法 ThreadPoolExecutor 中涉及关闭线程池方法,如下所示。 void ...
  • ThreadPoolExecutor关闭线程池的原理

    千次阅读 2020-09-07 18:30:04
    知识储备 - 线程池的5种状态 1. RUNNING 状态说明: 线程池处于RUNNING状态时,能够接收新的任务,并对已经...状态切换: 调用线程池的shutdown()方法后,线程池的状态RUNNING -> SHUTDOWN 3. STOP 状态说明: 线
  • 在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动、调度、管理线程的一大堆API了。...在新特征中,可以很容易控制线程的启动、执行和关闭过程,还可以很容易使用线程池的特性。
  • Spring环境中正确关闭线程池的姿势

    千次阅读 多人点赞 2020-07-19 10:58:32
    在Java System#exit 无法退出程序的问题探索一文末尾提到优雅停机的一种实现方案,要借助Shutdown Hook进行实现,本文,将继续探索优雅停机中遇到的一些问题:应用中线程池的优雅关闭 线程池正确关闭的姿势 在这一节...
  • spring项目优雅关闭线程池

    千次阅读 2020-07-30 18:10:25
    java中线程池的三个方法shutdown()、shutdownNow()和awaitTermination() shutdown: 拒绝新任务提交到线程池 待执行与正在执行的任务继续执行 shutdownNow: 拒绝提交新任务到线程池 取消队列中等待执行的任务 ...
  • 目录线程的两种执行方式:1.execute执行:2.submit执行:两者区别:线程池的两种关闭方式:1.shutdown():1.shutdownNow():两者区别:线程池的状态: 线程的两种执行方式: 1.execute执行: (new Runnable)无返回值的: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 114,092
精华内容 45,636
关键字:

关闭线程池的方法