线程的终止

   对于线程的终止或者中断,由于java中Thread.stop方法已经被弃用,如何终止一个线程,成为了一个挑战,不仅仅要考虑终止的条件也要考虑终止后的收尾工作。
大部分情况下,我们可以通过自己设置的标识例如m_stop布尔变量来,这样写run方法
public run ()
{
  while(!m_stop)
  {
   //add your works here.
  }
}
然后可以自己写一个Stop方法在里面将m_stop改变,就可以达到终止线程的目的。
但是如果在你的线程中,就是while循环中出现阻塞(大部分情况是wait,sleep或者IO阻塞等等),线程就停在里面,我们就无法通过判断m_stop的值来终止线程了。
这样我们可以通过另一种方式,调用interrupt()方法,这个方法是比较特别的,
通过测试,interrupt方法实现了这样的功能:
如果线程当前在sleep和wait状态下,会清除interrupt status, 并同时抛出异常.
而在非sleep和wait状态下,就会表明自己为interrupt status.
我们可以通过isInterrupted方法获得interrupt status。
也就是说如果线程处于阻塞状态,而且我们改变m_stop的值已经不起作用的时候,我们可以通过异常来终止线程。也就是在Stop方法里调用interrupt()方法,如果线程当前处于阻塞状态会产生一个异常。
例如:
    public void run() {
        while ( !m_stop) {
            System.out.println( "Thread running..." );
            try {
                Thread.sleep( 1000 );
            } catch ( InterruptedException e ) {
                System.out.println( "Thread interrupted..." );
            }
        }
        System.out.println( "Thread exiting under request..." );
    }
这样可以通过catch子句跳出run方法,从而终止线程。
总结:
终止线程的方法
1、通过标识设置,跳出while循环
2、通过异常跳出run方法。 

线程终止的方法和原理如下: ### 方法 - **使用 `interrupt()` 方法**:通过调用线程的 `interrupt()` 方法来设置线程的中断标志,线程内部可通过 `Thread.interrupted()` 或 `Thread.currentThread().isInterrupted()` 方法来检查该标志,从而决定是否终止线程。例如在以下代码中,`MyThread1` 线程在 `run` 方法里通过 `Thread.interrupted()` 检查中断标志,外部在主线程中调用 `myThread.interrupt()` 来尝试终止线程: ```java class MyThread1 extends Thread { @Override public void run() { while (!Thread.interrupted()) { try { System.out.println("线程 " + Thread.currentThread().getName() + " 正在执行"); Thread.sleep(10); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } public class Demo2 { public static void main(String[] args) throws InterruptedException { MyThread1 myThread = new MyThread1(); myThread.start(); Thread.sleep(100); myThread.interrupt(); System.out.println("mian线程是否终止 " + Thread.currentThread().isInterrupted()); } } ``` ### 原理 - **`interrupt()` 方法原理**:当调用 `interrupt()` 方法时,会设置线程的中断标志。如果线程处于阻塞状态(如调用了 `Thread.sleep()`、`Object.wait()` 等方法),会抛出 `InterruptedException` 异常,线程可根据该异常进行相应的处理,如终止线程。在上述示例中,`MyThread1` 线程在 `Thread.sleep(10)` 处可能会因为 `interrupt()` 方法抛出 `InterruptedException` 异常,不过这里代码选择抛出运行时异常,也可以在捕获异常后进行终止线程的操作。 ### 特殊情况 - **使用 `join()` 方法不当导致无法终止**:如果调用 `Thread.currentThread().join()`,线程会一直阻塞,因为它自己在等待自己结束,这会造成死锁,无法正常终止线程 [^2]。 ### `join()` 方法原理 `join()` 方法的底层是利用 `wait()` 方法实现。`join()` 方法是一个同步方法,当主线程调用 `t1.join()` 方法时,主线程先获得了 `t1` 对象的锁。`join()` 方法中调用了 `t1` 对象的 `wait()` 方法,使主线程进入了 `t1` 对象的等待池。其源码如下: ```java public final void join() throws InterruptedException { join(0); } public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } } ``` 当 `millis` 为 0 时,会通过 `while (isAlive())` 循环和 `wait(0)` 让主线程无限等待直到被 `notify`;当 `millis` 不为 0 时,会在指定时间内等待,超时则跳出循环 [^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值