思考一下
- 在线程1中如何终止线程2?
- stop()?还是System.exit()?还是其他方式
方式解答
1.使用stop()不可取
线程对象的stop()方法会直接杀死线程,假设此时使用了线程锁,当此时使用了stop()命令会导致线程锁无法释放,以至于程序出现严重的问题,其中最常见的是死锁。还可能导致资源泄露,因为其他线程无法获取到被持有的资源。这可能会导致内存泄露或者其他资源的持续占用,最终导致系统资源耗尽。
什么是死锁?
死锁是指两个或多个线程相互持有对方所需的资源,导致它们都在等待对方释放资源,从而永远无法继续执行下去。当发生死锁时,程序可能会完全停止响应,或者表现出非常低的性能。在生产环境中,死锁可能导致程序崩溃或系统不稳定。
2.System.exit(int)不可取
System.exit(int)此方法是停止所有线程,此做法会使程序整个终止掉。
详细解释
文章来源:https://www.toymoban.com/news/detail-811304.html
- 当调用
System.exit(int)
时,JVM 将立即终止当前程序的执行,并返回一个整数状态码。通常情况下,返回值 0表示程序正常结束,非零值表示程序出现了某种异常或错误。这意味着可以根据System.exit(int)
返回值来判断程序的结束状态,并在必要时采取相应的措施。 - 需要注意的是,调用
System.exit(int)
将立即终止程序的执行,因此任何在该方法调用之后的代码都将不会被执行。因此,需要小心使用该方法,避免在不必要的情况下过早地终止程序的执行。 - 通常情况下,不建议在常规的程序流程中经常使用
System.exit(int)
,除非在特定情况下需要强制结束程序的执行。更好的做法是通过返回值或异常来控制程序的执行流程。
正确停止: Two-phase Termination(两阶段终止)模式
- 将终止过程分成两个阶段,其中第一个阶段主要是线程 T1 向线程 T2发送终止指令,而第 二阶段则是线程 T2响应终止指令。
- Java 线程进入终止状态的前提是线程进入 RUNNABLE 状态,而利用java线程中断机制的interrupt()方法,可以让线程从休眠状态转换到RUNNABLE 状态。RUNNABLE 状态转换到终止状态,让 Java 线程自己执行完 run()方法,所以一般我们采用的方法是设置一个标志位,然后线程会在这个标志位检查,如果发现符合终止条件,则自动退出run() 方法。
两阶段终止模式是一种应用很广泛的并发设计模式,在 Java 语言中使用两阶段终止模式来终止线程,需要注意两个关键点:文章来源地址https://www.toymoban.com/news/detail-811304.html
- 仅检查终止标志位是不够的,因为线程的状态可能处于休眠态;
- 仅检查线程的中断状态也是不够的,因为我们依赖的第三方类库很可能没有正确处理中断异常.
例如:
Google Guava库中的com.google.common.io.Files
类中的copy
方法。在早期的版本中,这个方法可能没有正确处理中断异常。当在文件拷贝过程中线程被中断时,该方法可能会忽略中断并继续执行文件拷贝操作,而不会抛出InterruptedException
。开发人员可能需要手动捕获中断异常并进行适当的处理。
使用场景
- 安全地终止线程,比如释放该释放的资源;
- 要确保终止处理逻辑在线程结束之前一定会执行时,可使用该方法;
到了这里,关于设计模式之并发特定场景下的设计模式 Two-phase Termination(两阶段终止)模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!