Thread类的interrupt方法是用来中断一个线程的。
interrupt()方法不像stop方法强行终止一个线程。它只是把要被停止的线程设置成中断状态。而此时要被中断的线程是可以继续执行的。
public class MyThread extends Thread {
public void run(){
super.run();
for(int i=0; i<500000; i++){
System.out.println("i="+(i+1));
}
}
}
public class Run {
public static void main(String args[]){
Thread thread = new MyThread();
thread.start();
try {
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出结果:
...
i=499994
i=499995
i=499996
i=499997
i=499998
i=499999
i=500000
从输出结果可以看出,被中断的线程并没有停止执行。
被中断的线程可以通过isInterrupted()或者是interrupted()方法判断当前线程的中断状态是否标志为中断,然后终止线程。
public class MyThread extends Thread {
public void run(){
super.run();
for(int i=0; i<500000; i++){
if(this.interrupted()) {
System.out.println("线程已经终止, for循环不再执行");
break;
}
System.out.println("i="+(i+1));
}
}
}
public class Run {
public static void main(String args[]){
Thread thread = new MyThread();
thread.start();
try {
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出结果:
...
i=202053
i=202054
i=202055
i=202056
线程已经终止, for循环不再执行。
上面的示例虽然停止了线程,但是如果for语句后面还有语句,这些语句还是会继续。看下面的例子:
public class MyThread extends Thread {
public void run(){
super.run();
for(int i=0; i<500000; i++){
if(this.interrupted()) {
System.out.println("线程已经终止, for循环不再执行");
break;
}
System.out.println("i="+(i+1));
}
System.out.println("这是for循环外面的语句,也会被执行");
}
}
使用Run.java执行的结果是:
...
i=180136
i=180137
i=180138
i=180139
线程已经终止, for循环不再执行
这是for循环外面的语句,也会被执行
如何解决语句继续运行的问题? 看一下更新后的代码:
public class MyThread extends Thread {
public void run(){
super.run();
try {
for(int i=0; i<500000; i++){
if(this.interrupted()) {
System.out.println("线程已经终止, for循环不再执行");
throw new InterruptedException();
}
System.out.println("i="+(i+1));
}
System.out.println("这是for循环外面的语句,也会被执行");
} catch (InterruptedException e) {
System.out.println("进入MyThread.java类中的catch了。。。");
e.printStackTrace();
}
System.out.println("我不会被输出");
}
}
输出结果:
...
i=203798
i=203799
i=203800
线程已经终止, for循环不再执行
进入MyThread.java类中的catch了。。。
java.lang.InterruptedException
at thread.MyThread.run(MyThread.java:13)
通过异常的方式来结束线程。
isInterrupted()和interrupted()方法的区别
interrupted()方法是静态方法,它判断的是当前线程是否中断
public class MyThread extends Thread {
public void run(){
super.run();
for(int i=0; i<500000; i++){
i++;// System.out.println("i="+(i+1));
}
}
}
public class Run {
public static void main(String args[]){
Thread thread = new MyThread();
thread.start();
try {
Thread.sleep(2000);
thread.interrupt();
System.out.println("stop 1??" + thread.interrupted());
System.out.println("stop 2??" + thread.interrupted());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出结果:
stop 1??false
stop 2??false
当前线程是main线性,该线程不处于中断状态。再看下面的例子
public class Run2 {
public static void main(String args[]){
Thread.currentThread().interrupt();
System.out.println("stop 1??" + Thread.interrupted());
System.out.println("stop 2??" + Thread.interrupted());
System.out.println("End");
}
}
输出结果:
stop 1??true
stop 2??false
End
在这个例子中,中断的当前线程是main,所有第一结果为true。第二个结果为false是因为,调用了interrupted方法会清楚当前线程的中断状态。
接着看isInterrupted()方法。它判断的是调用它的对象所启动的线程是否处于中断状态,而不是判断当前线程。
public class Run4 {
public static void main(String[] args) {
Thread thread = new MyThread();
thread.start();
Thread.currentThread().interrupt();
System.out.println("stop 1??" + thread.isInterrupted());
System.out.println("stop 2??" + thread.isInterrupted());
}
}
运行结果:
stop 1??false
stop 2??false
这个例子中断的线程是当前线程main,可以看到输出结果为false。
public class Run4 {
public static void main(String args[]){
Thread thread = new MyThread();
thread.start();
thread.interrupt();
System.out.println("stop 1??" + thread.isInterrupted());
System.out.println("stop 2??" + thread.isInterrupted());
}
}
运行结果:
stop 1??true
stop 2??true
从这个例子可以看出isInterrupted()方法判断的是调用它的对象所启动的线程是否处于中断状态。也可以看出这个方法不会清除被中断线程的中断状态。