引子
本来以为interrupt()后,线程就立刻停止了,其实不是这样的!!!
interrupt()通知线程应该停止
interrupt()是Thread的实例方法,它通过设置线程中断状态,来提示线程应该停止,真正是否停止何时停止取决于程序员;interrupt()时,如果线程在WAITING/TIMED_WAITING状态(执行了wait()、wait(long)、join()、join(long)、sleep(long))则会清除中断状态,抛出InterruptedException,注不要使用stop来中止线程,此方法已不推荐使用,并会带来状态一致性问题。
interrupt()改变状态
Thread a = new Thread(new Runnable() {
@Override
public void run() {
int i=0;
while(true){
System.out.println(Thread.currentThread().isInterrupted()+"--"+(++i));
}
}
});
a.start();
a.interrupt();
System.out.println("线程被中断了");
线程被中断了
true--1
true--2
true--3
true--4
true--5
true--6
true--7
...
可以看到,执行了interrupt()后,线程为中断状态,但线程未停止。
一般的,如果接到线程终止,应该停止,如下
while(true){
if(Thread.currentThread().isInterrupted()){ // 通过判断中止状态来采取操作
break;
}
System.out.println(Thread.currentThread().isInterrupted()+"--"+(++i));
}
输出结果,没有输出数字
线程被中断了
waiting/timed_waiting状态,interrupt()线程抛出异常
线程处在waiting/timed_waiting状态,interrupt()导致目标线程抛出InterruptedException异常,并清除中断状态;
Thread a = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getState()+"-begin-"+Thread.currentThread().isInterrupted()); // 1
try {
Thread.sleep(2000); //7
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getState()+"-end-"+Thread.currentThread().isInterrupted()); //2
e.printStackTrace(System.out);
}
}
});
a.start(); //3
System.out.println(a.getState()+"--"+a.isInterrupted()); //4
a.interrupt(); //5
System.out.println(a.getState()+"--"+a.isInterrupted()); //6
输出结果有好几种情况,这是因为多线程交替执行导致,包括但不限于以下几种情况
这种情况的执行顺序是,345612
RUNNABLE--false //
RUNNABLE--true
RUNNABLE-begin-true
RUNNABLE-end-false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$1.run(Test.java:15)
at java.lang.Thread.run(Thread.java:745)
这种情况的执行顺序是,341562
RUNNABLE--false
RUNNABLE-begin-false
RUNNABLE--true
RUNNABLE-end-false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$1.run(Test.java:15)
at java.lang.Thread.run(Thread.java:745)
这种情况的执行顺序是,317456,咱们重点解释这种情况,a.start()后,接着执行a线程run方法,1输出false,执行到7,进入timed_waiting状态,线程切换到主线程执行4,输出false,执行5后,线程中断状态为true,继续执行5,输出true,调度器切换到a线程抛出异常清除中断状态,执行2输出false。
RUNNABLE-begin-false
TIMED_WAITING--false
TIMED_WAITING--true
RUNNABLE-end-false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$1.run(Test.java:15)
at java.lang.Thread.run(Thread.java:745)
interrupt() vs isInterrupted() vs interrupted()
- public void interrupt()
- 设置线程状态,如果线程处在WAITING/TIMED_WAITING状态,则抛出InterruptedException,并清除中断状态;
- public boolean isInterrupted()
- 获取线程中断状态;
- public static boolean interrupted()
- 获取当前线程中断状态,然后清除中断状态,也就是说,如果连续执行两次,第二次为false