您的位置:首页 > 编程语言 > Java开发

JAVA 线程中断interrupt()

2017-03-18 11:00 337 查看
线程中断有三种方法:

1、stop(),暴力中断,会导致事物不完整,已被废弃

2、flag标记法,用标记变量做循环条件,外部线程改变flag的值来达到中断线程的目的

3、interrupt()和isInterrupted()配合使用,本质上和方法2一样

重点看方法3如何实现

package com.nicovon;

public class ThreadTest extends Thread {

public static void main(String[] args) throws InterruptedException {
ThreadTest thread = new ThreadTest();
System.out.println("Start.");
thread.start();

Thread.sleep(3000);
System.out.println("interrupt thread");
thread.interrupt();
Thread.sleep(3000);
System.out.println("stop thread");
}

@Override
public void run(){
while (!this.isInterrupted()) {
System.out.println("Thread is running.");

long time = System.currentTimeMillis();
while (System.currentTimeMillis() - time < 1000);
}
}
}
运行结果:

Start.
Thread is running.
Thread is running.
Thread is running.
Thread is running.
interrupt thread
stop thread

Process finished with exit code 0


interrupte()方法会将中断状态status设置为true,注意这里的中断状态并不在Thread类中,而是一个底层标志,通过一些native方法来控制其值

初始时,status未设置,this.isInterrupted()返回false,一直循环,当主线程调用thread的interrupt()方法后,status被设置为true,循环终止

修改一下run()方法

public void run(){
while (!this.isInterrupted()) {
System.out.println("Thread is running.");

try {
Thread.sleep(1000);
System.out.println("run sleep 1000");
} catch (InterruptedException e) {
System.out.println("Here get an InterruptedException");
}
}
}


运行结果

Start.
Thread is running.
run sleep 1000
Thread is running.
run sleep 1000
Thread is running.
interrupt thread
Here get an InterruptedException
Thread is running.
run sleep 1000
Thread is running.
run sleep 1000
Thread is running.
stop thread
run sleep 1000
Thread is running.
run sleep 1000
Thread is running.


线程并没有正常中断,API中说

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be
cleared and it will receive an InterruptedException.

也就是说,在线程中使用sleep()等阻塞方法时调用interrupt()中断操作时,中断状态不会置为true,反而会被清空,并且抛出一个异常

如果在捕获异常等catch块中稍作修改

@Override
public void run(){
while (!this.isInterrupted()) {
System.out.println("Thread is running.");

try {
Thread.sleep(1000);
System.out.println("run sleep 1000");
} catch (InterruptedException e) {
System.out.println("Here get an InterruptedException");
this.interrupt();
}
}
}


运行结果

Start.
Thread is running.
run sleep 1000
Thread is running.
run sleep 1000
Thread is running.
interrupt thread
Here get an InterruptedException
stop thread

Process finished with exit code 0


如果知道中断状态status不在Thread类中,而是一个底层标志就很好理解了

更普遍的做法是将while放到try catch块里面,间接跳出循环

注意:interrupte只能中断可中断的阻塞,可中断的阻塞是指可以抛出interruptexception的阻塞,像IO阻塞和syncrnized块就属于不可中断阻塞
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 线程