您的位置:首页 > 其它

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

2017-08-21 10:23 399 查看
停止线程是在多线程开发时很重要的技术点,掌握此技术可以对线程的停止进行有效的处理。停止线程在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 对象是否已经是中断状态,但不清楚状态标志。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息