多线程基础四(一)、停止不了的线程(interrupted、isInterrupted)

停止线程是在多线程开发时很重要的技术点,掌握此技术可以对线程的停止进行有效的处理。停止线程在Java 语言中并不像 break 语句那样干脆,需要一些技巧性的处理。

interrupt() 方法,此方法并不像 break 语句那样,马上就停止线程。调用 interrupt() 方法仅仅是在当前线程中大了一个停止的标记,并不是真的停止线程。

public class MyThread extends Thread {
    @Override
    public void run() {
        super.run();
        for (int i = 0; i < 500000; i++) {
            System.out.println("i = " + (i +1));
        }
    }
}
public class Test {
    public static void main(String[] args) {
        try {
            MyThread thread = new MyThread();
            thread.start();
            Thread.sleep(1000);
            thread.interrupt();
        } catch (InterruptedException e) {
            System.out.println("main catch");
            e.printStackTrace();
        }
    }
    /*
    运行结果:
    ...
    i = 499997
    i = 499998
    i = 499999
    i = 500000
     */
}
从上面的运行结果可以看到,调用 interrupt() 方法并没有停止线程。那么如何停止线程呢?

在此之前,我们先来看看怎样判断一个线程是否是停止状态:

A. this.interrupted():测试当前线程是否已经中断,当前线程是指 运行 this.interrupted() 方法的线程。

B. this.isInterrupted():测试线程是否已经中断。

A. interrupted() 方法:再来看一个例子,还是用 MyThread 类,如下:

public class Test2 {
    public static void main(String[] args) {
        try {
            MyThread thread = new MyThread();
            thread.start();
            Thread.sleep(1000);
            thread.interrupt();
            //Thread.currentThread().interrupt();
            System.out.println("是否停止1 ? = " + thread.interrupted());
            System.out.println("是否停止2 ? = " + thread.interrupted());
        } catch (InterruptedException e) {
            System.out.println("main catch");
            e.printStackTrace();
        }
    }
    /*
    运行结果:
    i = 261886
    i = 261887
    是否停止1 ? = false
    是否停止2 ? = false
    i = 261888
    i = 261889
     */
}
虽然是在 thread 对象上调用 interrupted() 方法,但是运行 thread.interrupted() 方法的是 main 线程,而 main 线程没有中断过,所以结果是两个 false。
如果让 main 线程中断,那么会是什么结果呢?
public class Run {
    public static void main(String[] args) {
        Thread.currentThread().interrupt();
        System.out.println("是否停止1 ? = " + Thread.interrupted());
        System.out.println("是否停止2 ? = " + Thread.interrupted());
        System.out.println("end!");
    }
    /*
    运行结果:
    是否停止1 ? = true
    是否停止2 ? = false
    end!
     */
}

停止1 = true 可以理解,因为 main 线程被中断了,那么停止2 = false 是什么原因?官方帮助文档对 interrupted() 方法的解释是:测试当前线程是否已经中断,并且线程的中断状态由该方法清楚。也就是说,如果连续两次调用该方法,那么第二次将会返回 false(第一次调用和第二次调用中间当前线程没有再次被中断的话)。

B. isInterrupted() 方法:

public class Test3 {
    public static void main(String[] args) {
        try {
            MyThread thread = new MyThread();
            thread.start();
            Thread.sleep(1000);
            thread.interrupt();
            System.out.println("是否停止1 ? = " + thread.isInterrupted());
            System.out.println("是否停止2 ? = " + thread.isInterrupted());
        } catch (InterruptedException e) {
            System.out.println("main catch");
            e.printStackTrace();
        }
        System.out.println("end!");
    }
    /*
    运行结果:
    i = 280727
    i = 280728
    i = 280729
    是否停止1 ? = true
    是否停止2 ? = true
    end!
    i = 280730
     */
}
从结果中看到,isInterrupted() 方法并未清除状态标志,所以结果是两个 true。

总结一下:

1) interrupt():该方法并不会真正的停止线程。

2)interrupted():测试当前线程是否已经是中断状态,执行后具有将状态标志清除为 false 的功能。

3)isInterrupted():测试线程 Thread 对象是否已经是中断状态,但不清楚状态标志。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值