Java并发之取消和关闭

1 任务取消
—协作方式:当需要停止时,它们首先会清除当前正在执行的工作。
—如果外部代码能在某个操作正常完成之前将其置入“完成”状态,那么这个操作就可以称为可取消的。
—取消某个操作的原因包括:
· 用户请求取消。
· 有时间限制的操作。
· 应用程序事件。
· 错误。
· 关闭。
—一个可取消的任务必须拥有取消策略,该策略详细地定义了取消操作的:
· How:即其他代码如何请求取消该任务;
· When:任务在何时检查是否已经请求了取消;
· What:在响应取消请求时应该执行哪些操作。

2 中断
—线程中断是一种协作机制,线程可以通过这种机制来通知另一个线程,告诉它在合适的或者可能的情况下停止当前工作,并转而执行其他的工作。
—每个线程都有一个boolean类型的中断状态。当中断线程时,这个线程的中断状态被设置为true。
—在Thread中包含了以下与中断相关的方法:
· interrupt方法能中断目标线程;
· isInterrupted方法能返回目标线程的中断状态;
· 静态的interrupted方法将清除当前线程的中断状态,并返回它之前的值。
—阻塞库方法,如Thread.sleep和Object.wait等,都会检查线程何时中断,并且在发现中断时提前返回。它们在响应中断时执行的操作包括:清除中断状态,抛出InterruptedException。
—当线程在非阻塞状态下中断时,它的中断状态将被设置,然后根据将被取消的操作来检查中断状态以判断发生了中断。
—调用interrupt并不意味着立即停止目标线程正在进行的工作,而只是传递了请求中断的消息。
—通常,中断是实现取消的最合理方式。
(1)中断策略
—中断策略规定线程如何解释某个中断请求:如当发现中断请求时,应该做哪些工作,哪些工作单元对于中断来说是原子操作,以及以多快的速度来响应中断。
—最合理的中断策略:尽快退出,在必要时进行清理,通知某个所有者该线程已经退出。
—其他中断策略:暂停服务或重新开始服务。
—由于每个线程拥有各自的中断策略,因此除非你知道中断对该线程的含义,否则就不应该中断这个线程。
(2)响应中断
—处理中断异常的两种策略(具体见第五章):
—传递异常。
—恢复中断状态。
—只有实现了线程中断策略的代码才可以屏蔽中断请求,在常规的任务和库代码中都不应该屏蔽中断请求。

3 停止基于线程的服务
—除非拥有某个线程,否则不能对该线程进行操控。
—线程的所有者是创建该线程的类,如线程池是其工作者线程的所有者。
—线程的所有权是不可传递的:应用程序可以拥有服务,服务也可以拥有工作者线程,但应用程序并不能拥有工作者线程。
—对于持有线程的服务,只要服务的存在时间大于创建线程的方法的存在时间,那么服务就应该提供生命周期方法来关闭它自己以及它所拥有的线程。

4 处理非正常的线程终止
—导致线程提前死亡的最主要原因就是RuntimeException。由于这些异常表示出现了某种编程错误或者其他不可修复的错误,因此它们通常不会被捕获。
—可能出现的严重后果:如由于线程泄露而造成Timer表示的服务将永远无法使用。
—解决方案:
· 在try-catch代码块中调用这些任务,从而能捕获那些未检查的异常。或者也可以使用try-finally代码块来确保框架能够知道线程非正常退出的情况,并做出正确的响应。
· 在Thread API中提供了UncaughtExceptionHandler,它能检测出某个线程由于未捕获的异常而终结的情况。如果没有提供任何异常处理器,默认的行为是将栈追踪信息输出到System.err。

5 JVM关闭
—JVM既可以正常关闭,也可以强行关闭。
—正常关闭的方式有:
· 当最后一个正常(非守护)线程结束时;
· 当调用了System.exit时;
· 通过其他特定于平台的方法关闭时,如发送了SIGINT信号或键入Ctrl-C。
—强行关闭的方式有:
· 调用Runtime.halt;
· 在操作系统中杀死JVM进程。
(1)关闭钩子
—关闭钩子是指通过Runtime.addShutdownHook注册的但尚未开始的线程。
—关闭钩子可以用于实现服务·或应用程序的清理工作,例如删除临时文件等。
—JVM并不能保证关闭钩子的调用顺序。
—关闭钩子应该是线程安全的;而且,关闭钩子不应该对应用程序的状态或者JVM的关闭原因做出任何假设;最后·,关闭钩子必须尽快退出,因为它会延迟JVM的结束时间。
(2)守护线程
—线程可分为:普通线程和守护线程。
—在JVM启动时创建的的所有线程中,除了主线程,其他线程都是守护线程。
—当创建一个新线程时,新线程将继承创建它的线程的守护状态。
—普通线程和守护线程的区别仅在于当线程退出时发生的操作。当一个线程退出时,JVM会检查其他正在运行的线程,如果这些线程都是守护线程,那么JVM会正常退出操作。当JVM停止时,所有仍然存在的守护线程都将被抛弃,既不会执行finally代码块,也不会执行回卷栈,而只是直接退出。
(3)终结器
—定义了finalize方法。
—必须对终结器的访问操作进行同步。
—缺点:终结器并不能保证它们将在何时运行甚至是否会运行;并且复杂的终结器通常还会在对象上产生巨大的性能开销;编写正确的终结器是非常困难的。
—通常,通过使用finally代码块和显式的close方法,能够比终结器更好地管理资源。
—适用情况:当需要管理对象,并且该对象持有的资源是通过本地方法获得的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值