首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

关闭线程的正确方法:“优雅”的中断

正是由于以上原因,大多数拥塞的库函数在检测到中断都是抛出中断异常(InterruptedException)作为中断响应,让线程的所有者去处理,而不是去真的中断当前线程。...但是,让以上的日志服务停下来其实并非难事,因为拥塞队列的take方法支持响应中断,这样直接关闭服务的方法就是强行关闭,强行关闭的方式不会去处理已经提交但还未开始执行的任务。...但是,关闭日志服务前,拥塞队列中可能还有没有及时打印出来的日志消息,所以强行关闭日志服务并不合适,需要等队列中已经存在的消息都打印完毕之后再停止,这就是平缓关闭,也就是在关闭服务时会等待已提交任务全部执行完毕之后再退出...平缓关闭的日志服务如下,其采用了类似信号量的方式记录队列中尚未处理的消息数量。...处理非正常线程终止 导致线程非正常终止的主要原因就是RuntimeException,其表示为不可修复的错误。一旦子线程抛出异常,该异常并不会被父线程捕获,而是会直接抛出到控制台。

3.5K31

Java线程池详解

设置maximumPoolSize也用不到,因为队列装不满,永远不需要创建新的非核心线程。但是也有风险,处理任务的速度跟不上提交的速度,可能造成内存浪费或者OOM。...10.停止线程池的正确方法 10.1 shutdown   不一定立即停止。执行了该方法之后,后面再请求执行的任务会拒绝,当前线程正在执行的任务和任务队列等待的任务还是会执行完才会停止线程池。...队列还有70各任务等待,正在执行10个,已完成20个。 那总不能每次执行一个新任务看是否被拒绝来判断是否正在停止吧?...,线程池正在执行的线程收到中断信号,并停止处理等待队列中的的任务,最后将所有未执行的任务以列表的形式返回 public class ShutDown { public static void main...任务队列(taskQueue) 存放任务的队列有很多种,把没有处理的任务放在队列中,因为线程池会同时有多个线程去队列中取任务,所以任务队列必须是支持并发的。

39210
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Java多线程详解

    只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。...栗子:假如有一个新任务提交时,线程池中如果有空闲的线程则立即使用空闲线程来处理任务,如果没有,则会把这个新任务存在一个任务队列中,一旦有线程空闲了,则按FIFO方式处理任务队列中的任务。...栗子:假如该线程池中的所有线程都正在工作,而此时有新任务提交,那么将会创建新的线程去处理该任务,而此时假如之前有一些线程完成了任务,现在又有新任务提交,那么将不会创建新线程去处理,而是复用空闲的线程去处理新任务...这里的要点在于,ForkJoinPool需要使用相对少的线程来处理大量的任务。比如要对1000万个数据进行排序,那么会将这个任务分割成两个500万的排序任务和一个针对这两组500万数据的合并任务。...以此类推,对于500万的数据也会做出同样的分割处理,到最后会设置一个阈值来规定当数据规模到多少时,停止这样的分割处理。比如,当元素的数量小于10时,会停止分割,转而使用插入排序对它们进行排序。

    62210

    Java 多线程详解

    只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的 I/O 设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。...栗子:假如有一个新任务提交时,线程池中如果有空闲的线程则立即使用空闲线程来处理任务,如果没有,则会把这个新任务存在一个任务队列中,一旦有线程空闲了,则按 FIFO 方式处理任务队列中的任务。...栗子:假如该线程池中的所有线程都正在工作,而此时有新任务提交,那么将会创建新的线程去处理该任务,而此时假如之前有一些线程完成了任务,现在又有新任务提交,那么将不会创建新线程去处理,而是复用空闲的线程去处理新任务...比如要对 1000 万个数据进行排序,那么会将这个任务分割成两个 500 万的排序任务和一个针对这两组 500 万数据的合并任务。...以此类推,对于 500 万的数据也会做出同样的分割处理,到最后会设置一个阈值来规定当数据规模到多少时,停止这样的分割处理。比如,当元素的数量小于 10 时,会停止分割,转而使用插入排序对它们进行排序。

    55710

    深入浅出parallelStream

    这里的要点在于,ForkJoinPool需要使用相对少的线程来处理大量的任务。比如要对1000万个数据进行排序,那么会将这个任务分割成两个500万的排序任务和一个针对这两组500万数据的合并任务。...以此类推,对于500万的数据也会做出同样的分割处理,到最后会设置一个阈值来规定当数据规模到多少时,停止这样的分割处理。比如,当元素的数量小于10时,会停止分割,转而使用插入排序对它们进行排序。...,比如A线程负责处理A队列里的任务。...但是有的线程会先把自己队列里的任务干完,而其他线程对应的队列里还有任务等待处理。干完活的线程与其等着,不如去帮其他线程干活,于是它就去其他线程的队列里窃取一个任务来执行。...而在这时它们会访问同一个队列,所以为了减少窃取任务线程和被窃取任务线程之间的竞争,通常会使用双端队列,被窃取任务线程永远从双端队列的头部拿任务执行,而窃取任务的线程永远从双端队列的尾部拿任务执行。

    1.3K50

    线程池技术之:ThreadPoolExecutor 源码解析

    如果核心线程池满了,判断队列是否满了,如果队列没满,将任务放在队列中     3. 如果队列满了,则判断线程池是否已满,如果没满,创建线程执行任务     4....当队列已放不下任务,且创建的线程已达到 maximum 后,则不能再处理任务,直接将任务交给饱和策略 AbortPolicy: 直接抛弃(默认) CallerRunsPolicy...当线程池已关闭,则将刚刚添加的任务移除,走reject策略 if (!...如果队列满了,则判断线程池是否已满,如果没满,创建线程执行任务; 4. 如果线程池也满了,则按照拒绝策略对任务进行处理; 2.1. 添加新的worker 一个worker,即是一个工作线程。...void tryTerminate() { for (;;) { int c = ctl.get(); // 线程池正在运行、正在清理、已关闭但队列还未处理完

    32210

    Java并发编程学习14-探索基于线程的服务如何优雅关闭

    由于它是 “先判断再运行”,如果生产者调用 log 方法,在判断“已请求关闭” 标志时,发现该服务还没有关闭,此时在调用 put 之前,正好关闭服务,那生产者仍然会将日志消息放入队列,这同样会使得生产者可能在调用..."毒丸" 对象另一种关闭生产者--消费者服务的方式就是使用 “毒丸(Poison Pill)” 对象:它是指一个放在队列上的对象,当从队列中取到该对象时,服务立即停止。...在 FIFO(先进先出)队列中,“毒丸” 对象将确保消费者在关闭之前首先完成队列中的所有工作,在提交 “毒丸” 对象之前提交的所有工作都会被处理,而生产者在提交了 “毒丸” 对象后,将不会再提交任何工作...只执行一次的服务如果某个方法需要处理一批任务,并且当所有任务都处理完成后才返回,那么可通过一个私有的 Executor 来简化服务的生命周期管理,其中该 Executor 的生命周期是由这个方法来控制的...当爬虫程序关闭时,无论是还没有开始的任务,还是那些被取消的任务,都将记录它们的 URL,因此当爬虫程序重新启动时,就可以将这些 URL 的页面抓取任务加入到任务队列中。

    12121

    深入浅出vue_深入浅出pandas

    这里的要点在于,ForkJoinPool需要使用相对少的线程来处理大量的任务。比如要对1000万个数据进行排序,那么会将这个任务分割成两个500万的排序任务和一个针对这两组500万数据的合并任务。...以此类推,对于500万的数据也会做出同样的分割处理,到最后会设置一个阈值来规定当数据规模到多少时,停止这样的分割处理。比如,当元素的数量小于10时,会停止分割,转而使用插入排序对它们进行排序。...,比如A线程负责处理A队列里的任务。...但是有的线程会先把自己队列里的任务干完,而其他线程对应的队列里还有任务等待处理。干完活的线程与其等着,不如去帮其他线程干活,于是它就去其他线程的队列里窃取一个任务来执行。...而在这时它们会访问同一个队列,所以为了减少窃取任务线程和被窃取任务线程之间的竞争,通常会使用双端队列,被窃取任务线程永远从双端队列的头部拿任务执行,而窃取任务的线程永远从双端队列的尾部拿任务执行。

    44610

    如何停止中断一个运行中的线程

    # 面试题: 如何正确地停止/中断一个运行中的线程 哪些情况下线程会停止 如何处理不可中断的阻塞 # 核心思想 使用interrupt()来通知,而不是强制。...1.1 线程未处理中断: /** * 正确停止线程---run()方法内没有sleep()或者wait()方法-未处理中断信号 * * @author futao * @date 2020/6/...原因是:我们并未处理线程的中断信号。 1.2 对程序进行改进:响应中断。...原因:sleep()在响应了中断之后,清除了线程的中断状态。那么while判断时不知道线程被中断了。...处理这类问题的方式要视情况而定,大概思路是手动编写程序检测线程的中断状态,如果线程被中断,则手动调用例如InputStream.close()方法来关闭流,实现停止线程。

    2K30

    21.3 Java 线程池

    这样做立即生效,但是风险也比较大; shutdown() 将线程池状态置为 SHUTDOWN,并不会立即停止。它停止接收外部 submit 的任务,内部正在跑的任务和队列里等待的任务,会执行完。...企图立即停止,事实上不一定: 跟shutdown()一样,先停止接收外部提交的任务 忽略队列里等待的任务 尝试将正在跑的任务 interrupt 中断 返回未执行的任务列表 awaitTermination...然后返回 true(shutdown 请求后所有任务执行完毕)或 false(已超时) 总结 优雅的关闭,用shutdown(), 之后不能再提交新的任务进去 想立马关闭,并得到未执行任务列表,用shutdownNow...() awaitTermination()并不具有提交的功能, awaitTermination()是阻塞的,返回结果是线程池是否已停止(true/false);shutdown()不阻塞。...明确拒绝任务时的行为 任务队列总有占满的时候,这是再 submit() 提交新的任务会怎么样呢?

    34320

    如何停止中断一个运行中的线程

    # 面试题: 如何正确地停止/中断一个运行中的线程 哪些情况下线程会停止 如何处理不可中断的阻塞 # 核心思想 使用interrupt()来通知,而不是强制。...1.1 线程未处理中断: /** * 正确停止线程---run()方法内没有sleep()或者wait()方法-未处理中断信号 * * @author futao * @date 2020/6/...原因是:我们并未处理线程的中断信号。 ? 1.2 对程序进行改进:响应中断。...原因:sleep()在响应了中断之后,清除了线程的中断状态。那么while判断时不知道线程被中断了。...处理这类问题的方式要视情况而定,大概思路是手动编写程序检测线程的中断状态,如果线程被中断,则手动调用例如InputStream.close()方法来关闭流,实现停止线程。

    3.2K10

    探索JAVA并发 - 线程池详解

    相比于为每个任务分配一个线程,在线程池中执行任务优势更多: 1.线程复用:线程池中的线程是可以复用的,省去了创建、销毁线程的开销,提高了资源利用率(创建、销毁等操作都是要消耗系统资源的)和响应速度(任务提交过来线程已存在就不用等待线程创建了...* * @param command 可执行的任务 * @throws RejectedExecutionException 任务可能被拒绝(当Executor处理不了的时候...handler : 任务被拒绝后的处理器,默认的处理器会直接抛出异常,建议重新实现 配合源码,效果更佳: public class ThreadPoolExecutor extends AbstractExecutorService...shutdown 停止接收新任务(继续提交会被拒绝,执行拒绝策略),但已提交的任务会继续执行,全部完成后线程池彻底关闭; shutdownNow 立即停止线程池,并尝试终止正在进行的线程(通过中断),返回没执行的任务集合...(关于中断: 如何处理线程中断) 一般先调用 shutdown 让线程池停止接客,然后调用 awaitTermination 等待正在工作的线程完事。

    31420

    java高并发系列 - 第20天:JUC中的Executor框架详解2

    说一下其内部原理,ExecutorCompletionService创建的时候会传入一个线程池,调用submit方法传入需要执行的任务,任务由内部的线程池来处理;ExecutorCompletionService...内部有个阻塞队列,任意一个任务完成之后,会将任务的执行结果(Future类型)放入阻塞队列中,然后其他线程可以调用它take、poll方法从这个阻塞队列中获取一个已经完成的任务,获取任务返回结果的顺序和任务执行完成的先后顺序一致...completionQueue是用来存储任务结果的阻塞队列,默认用采用的是LinkedBlockingQueue,也支持开发自己设置。...} } 输出: 1564667625648:2 1564667627652:4 1564667629649:6 1564667631652:8 1564667633651:10 代码中传入了一批任务进行处理...,最终将所有处理完成的按任务完成的先后顺序传递给Consumer进行消费了。

    48520
    领券