停止线程的方法

本文详细介绍了如何使用interrupt机制安全地停止线程,包括正确和错误的停止方法,不可中断阻塞的处理策略,以及响应中断的关键函数。特别强调了stop/suspend的过时性和volatile boolean的局限性。

原理介绍

使用interrupt来通知,而不是强制。

如何正确的停止线程

  • 通常线程会在什么情况下停止
    run方法执行完毕;出现异常且未捕获;

  • 正确的停止方法:interrupt请求停止线程

    • 通常情况(run方法内没有sleep或wait等会造成阻塞的方法)
      通过thread.interrupt()中断线程,然后通过Thread.currentThread().isInterrupted()判断是否中断线程。
      在这里插入图片描述

    • 线程可能阻塞
      阻塞时用interrupt停止线程是通过抛出InterruptedException来停止
      注:在抛出InterruptedException后会清除掉Thread.currentThread().isInterrupted()标记位。

    • 在while内try/catch会无法停止,需要包住while

  • 实际开发中两种最佳实践

    • 优先选择:传递中断。将出现的InterruptedException不用try/catch处理,而是传递给run方法处理。
    • 不想或者无法传递:恢复中断。在捕获InterruptedException的catch语句中通过Thread.currentThread().interrupt()重新设置中断。
      不应该屏蔽中断:即不应该既不将异常传递给run方法也不重新设置中断。
  • 响应中断的方法

    1. Object.wait()常用
    2. Thread.sleep()常用
    3. Thread.join()常用
    4. java.util.concurrent.BlockingQueue.take()/put(E)阻塞队列
    5. java.util.concurrent.locks.Lock.lockInterruptibly()锁
      。。。

错误的停止方法

  • stop()方法:已过时。该方法具有固定的不安全性。用 Thread.stop() 来终止线程将释放它已经锁定的所有监视器。会导致线程运行一半突然停止,没办法完成一个基本单位的操作,造成脏数据。
  • suspend和resume:挂起不会释放锁,容易造成死锁。
  • volatile boolean变量控制停止:待停止的线程内部发生了阻塞会导致volatile变量无法停止线程。

停止线程相关重要函数

  • static boolean interrupted():检测当前线程是否被中断,会清除线程中断状态
  • boolean isInterrupted():同上,调用同一个函数,但是不会清除线程中断状态。
  • Thread.interrupted():看调用该语句的线程是否中断。

面试题:

  • 如何停止线程:

    1. 原理:用interrupt来请求。可以保证数据安全而且适用于阻塞场景。
    2. 一个线程调用interrupt,被中断的线程配合:请求方发出请求信号、被停止方检查中断信号并在可能出现InterruptedException的地方处理信号、子方法被调用方向上抛出异常或者再次设为中断状态。
    3. 错误:stop/suspend过时:数据安全与死锁。volatile的boolean无法处理长时间阻塞的情况。
  • 如何处理不可中断阻塞
    没有通用方法,针对不同的场景使用不同的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值