博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Java并发编程实战] 第7章 取消与关闭
阅读量:2342 次
发布时间:2019-05-10

本文共 1575 字,大约阅读时间需要 5 分钟。

任务取消

  • 每个线程有一个boolean类型的中断状态,中断线程时被置为true;静态的interrupted方法将清除当前线程的中断状态,并返回它之前的值,这是清除中断状态的唯一方法

  • 阻塞库方法(Thread.sleep/Object.wait)会检查线程何时中断,发现中断提前返回:清除中断状态、抛出InterruptedException。

  • 当线程在非阻塞状态下中断时,它的中断状态将被设置,然后根据将被取消的操作来检查中断状态以判断发生了中断。通过这样的方法,中断操作将变得“有黏性”——如果不触发InterruptedException,中断状态将一直保持,直到明确地清除中断状态

  • 任务应该包含取消策略,线程应该包含中断策略,线程应该只能由其所有者中断;通常,中断是实现取消的最合理方法;在中断线程之前,应该了解它的中断策略

  • Thread的join的不足:无法直到执行控制是因为线程正常退出而返回还是因为join超时而返回

  • Future的cancel方法:如果任务已经结束,那么执行取消操作也不会带来任何影响;如果任务正在执行,将被中断

  • 不可中断的阻塞

    • Java.io包中的同步Socket I/O、Java.io包中的同步I/O、Selector的异步I/O、获取某个锁

    • 中断请求只能设置线程的中断状态,阻塞方法不会检查中断状态,然后提前返回或抛出异常

    • 改写执行不可中断操作的线程的interrupt方法,解决使线程阻塞的原因(如关闭socket连接等),然后调用super.interrupt,使得该线程停止执行当前工作且可以被中断

    • 进一步,可以使用ThreadPoolExecutor中的newTaskFor方法返回一个定制的FutureTask,封装非标准的取消操作

停止基于线程的服务

  • PrintWriter字符流类是线程安全的

  • 将关闭线程的工作委托给ExecutorService(shutdown和awaitTermination)

  • 还可以使用毒丸对象:必须要生产者消费者数量已知,而且要在无界队列中,毒丸对象才能可靠工作

  • shutdownNow的局限性:在任务执行最后一条指令和线程池将任务记录为“结束”的两个时刻之间,线程池可能被关闭,所以可能任务执行完了却被标记为取消

非正常的任务终止

  • 如果任务抛出了一个未检查异常,那么它能使线程终结,但会首先通知框架该线程已经终结;

  • 可以通过try/catch捕获;Thread API中还提供了UncaughtExceptionHandler,能检测出某个线程由于未捕获的异常而终结的情况。

  • 只有通过execute提交的任务,才能将它抛出的异常交给未捕获异常处理器,而通过submit提交的任务,无论是抛出的未检查异常还是已检查异常,都将被认为是返回状态的一部分。如果由submit提交的任务由于抛出了异常而结束,这个异常会被Future.get封装在ExecutionException中重新抛出

JVM关闭

  • 可以通过调用Runtime.halt或者在操作系统中“杀死”JVM进程,强行关闭JVM

  • 关闭钩子

    • 通过Runtime.addShutdownHook注册的但尚未开始的线程;

    • 正常关闭中,JVM首先调用所有已注册的关闭钩子,所有关闭钩子执行结束,如果runFinalizersOnExit为true,JVM将运行终结器,再停止;

    • 当被强行关闭时,只会关闭JVM,不会运行关闭钩子

  • 守护线程:执行辅助工作,不阻碍JVM的关闭,垃圾回收器

  • 终结器:一些资源(文件句柄或套接字句柄)当不再被需要时,要显式地交还给操作系统。为了实现这个功能,GC对那些定义了finalize方法的对象会进行特殊处理:在GC释放它们后,调用它们的finalize方法,保证一些持久化的资源被释放

转载地址:http://glkvb.baihongyu.com/

你可能感兴趣的文章
ReactJS-每次调用“ setState”时都会调用渲染吗?
查看>>
如何在Ubuntu上安装Boost
查看>>
如何在变更事件中使用广播?
查看>>
如何解决错误:使用nodejs时监听EADDRINUSE?
查看>>
如何检查批处理文件中是否存在文件[重复]
查看>>
抛出异常的Java 8 Lambda函数?
查看>>
状态栏和导航栏显示在iOS 7中我视图的边界上
查看>>
backbone.js的目的是什么?
查看>>
instanceof和Class.isAssignableFrom(...)有什么区别?
查看>>
使用AngularJS的ng-options使用select
查看>>
解析JSON时出现“意外令牌o”错误[重复]
查看>>
如何在PHP中获取文件扩展名? [重复]
查看>>
Scalaz迭代:“提升”`EnumeratorT`以匹配`IterateeT`为“更大”的monad
查看>>
我应该如何在OSX上设置JAVA_HOME
查看>>
如何显示过滤的ng-repeat数据的长度
查看>>
@import vs #import - iOS 7
查看>>
如何使用C#解析JSON?
查看>>
我已经安装了哪个版本的Python?
查看>>
ng-if和ng-show / ng-hide有什么区别
查看>>
将Java InputStream的内容写入OutputStream的简便方法
查看>>