本来想自己去写一写 ,但是在网上找到一篇比较完整的文章,自己写也写的没那好,所以就直接转载好了!
文章来源:https://www.cnblogs.com/carmanloneliness/p/3516405.html
本文将上述博客中所引用的一个例子来进一步分析,帮助读者更好的理解interrupt()的具体实现原理:
案例:
package interrupt;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
Main main = new Main();
Thread t = new Thread(main.runnable);
System.out.println("mainmainmain");
t.start();//主线程调用t线程开始执行
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.interrupt();
}
Runnable runnable = new Runnable() {
@Override
public void run() {
int i = 0;
try {
while (i < 1000) {
Thread.sleep(500);//t线程休眠 会清除interrupt的状态
System.out.println(i++);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
运行结果:
mainmainmain
0
1
2
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at interrupt.Main$1.run(Main.java:27)
at java.lang.Thread.run(Thread.java:619)
为什么运行结果会是这样呢?
首先,当主线程调用t.start();的时候,t线程开始执行,此时t线程与主线程同时执行,然后执行到Thread.sleep(2000)时,此时主线程进入阻塞状态,而t线程继续执行,所以我们会看到打印出了0,1,2,这三个值,当休眠过后主线程继续执行,t线程也执行,刚好在某一个时间点主线程去尝试打断t线程执行时,即执行t.interrupt()时,而此时t线程刚执行完t.sleep()处于阻塞状态,所以主线程去打断一个处于阻塞状态的线程执行时会清除该线程(t线程的)的中断状态,并向向上抛出一个InterruptedException 使线程结束。
由源码的解释 If this thread is blocked in an invocation of the {@link Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link Object#wait(long, int) wait(long, int)} methods of the {@link Object} class, or of the {@link #join()}, {@link #join(long)}, {@link #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)}, methods of this class, then its interrupt status will be cleared and it will receive an {@link InterruptedException} 可论证。
同时我们还可以知道一点:
Unless the current thread is interrupting itself, which is always permitted.(源码中关于interrupt()的描述)
这句话的意思是,除非某线程自己中断自己,否则,该线程则一直执行。
用上文的例子来说就是,如果t线程的执行体里没有调用sleep()(上述中的自己打断自己),则 t.interrupt();将会失效。