前言
记录一下,方便自己查阅。
正文
Thread中断主要涉及如下几个方法:
下面单独介绍一下。
interrupt()
interrupt()使线程中断。
重点:当线程调用interrupt()时,仅仅设置中断标志位true,此时线程是不会被中断的,会一直执行直到结束。
为了让人易懂,简单测试一下。
测试一
先定义一个MyThread类(比较简单,只是为了测试而已)
private class MyThread extends Thread { public MyThread(String name) { setName(name); } @Override public void run() { super.run(); Log.d(TAG, "run thread name : " + getName() + " start "); for (int i = 0; i < 1000; i++) { Log.d(TAG, "run thread name : " + getName() + " [ " + i + " ] "); } Log.d(TAG, "run thread name : " + getName() + " end , isInterrupted() : " + isInterrupted()); } }
MyThread myThreadA = new MyThread("Thread_A"); myThreadA.start(); try { Thread.sleep(10); } catch (InterruptedException e) { throw new RuntimeException(e); } Log.d(TAG, "myThreadA.interrupt() : "); myThreadA.interrupt();
下面打印日志:
// ...为省略,打印太多了。 run thread name : Thread_A start ... run thread name : Thread_A [ 102 ] ... myThreadA.interrupt() ... run thread name : Thread_A [ 999 ] run thread name : Thread_A end , isInterrupted() : true
从上面可以看出,调用interrupt()后,并不会终止线程中断,直到线程for循环结束,最后打印时中断标志位以为true。
-
interrupt()会改变中断标志位位true
-
interrupt()不会打断Thread执行任务,直到自动结束。
测试二
当然,如果线程调用了wait方法、join方法或者sleep方法而被阻塞挂起,此时如果线程A的interrupt(),线程会在调用这些方法的地方抛出InterruptedException异常而返回。
下面我们在ThreadA中的for循环中添加sleep(),其他的保持不变。
private class MyThread extends Thread { public MyThread(String name) { setName(name); } @Override public void run() { super.run(); Log.d(TAG, "run thread name : " + getName() + " start "); for (int i = 0; i < 1000; i++) { Log.d(TAG, "run thread name : " + getName() + " [ " + i + " ] "); try { sleep(10); } catch (InterruptedException e) { Log.d(TAG, "run e: "+ e); break;//退出for循环 } } Log.d(TAG, "run thread name : " + getName() + " end , isInterrupted() : " + isInterrupted()); } }
调用那部分不改变,这里省略,打印日志如下:
run thread name : Thread_A start run thread name : Thread_A [ 0 ] myThreadA.interrupt() run e: java.lang.InterruptedException run thread name : Thread_A end , isInterrupted() : false
很快就在sleep()中收到InterruptedException,然后我们退出了for循环。
-
interrupt() 时,如果有sleep()等代码,会抛出InterruptedException
-
在1(基础上)抛出异常后最后中断状态为false
也就是说出行InterruptedException后,会影响中断标志位。
由于对Thread源码不是很了解,在,有兴趣的可以看Thread相关的源码。
后续后续有空看一下,这里先插个眼!
isInterrupted()
检测当前线程是否被中断,如果是返回true,否则返回false。
下面测试一下,在ThreadA中新增isInterrupted()判断,如果为true,就结束for循环
private class MyThread extends Thread { public MyThread(String name) { setName(name); } @Override public void run() { super.run(); Log.d(TAG, "run thread name : " + getName() + " start "); for (int i = 0; i < 1000; i++) { Log.d(TAG, "run thread name : " + getName() + " [ " + i + " ] "); if(isInterrupted()){ Log.d(TAG, "run isInterrupted break: "); break; } } Log.d(TAG, "run thread name : " + getName() + " end , isInterrupted() : " + isInterrupted()); } }
其他的保持不变[跟interrupt()中代码一样,这里略],打印日志如下:
run thread name : Thread_A start run thread name : Thread_A [ 0 ] ... myThreadA.interrupt() : run thread name : Thread_A [ 100 ] run thread name : Thread_A [ 101 ] run isInterrupted break: run thread name : Thread_A end , isInterrupted() : true
执行中断后,isInterrupted()返回true,然后break退出循环。
-
interrupt()时,isInterrupted()会返回true
-
isInterrupted()返回结果后,不会改变中断标志,所以打印依旧为true
interrupted()
如果线程被中断,返回true,否则返回false。
如果interrupted()返回true后,会把中断标志位清除,置为false。
下面简单的测试一下。新增interrupted()判断,如果返回true,就break线程中的for选好
private class MyThread extends Thread { public MyThread(String name) { setName(name); } @Override public void run() { super.run(); Log.d(TAG, "run thread name : " + getName() + " start "); for (int i = 0; i < 1000; i++) { Log.d(TAG, "run thread name : " + getName() + " [ " + i + " ] "); if(interrupted()){ Log.d(TAG, "run interrupted break : "); break; } } Log.d(TAG, "run thread name : " + getName() + " end , isInterrupted() : " + isInterrupted()); } }
执行后日志打印。
run thread name : Thread_A start run thread name : Thread_A [ 0 ] ... myThreadA.interrupt() : run thread name : Thread_A [ 242 ] run interrupted break : run thread name : Thread_A end , isInterrupted() : false
-
调用interrupt()后,interrupted()返回true
-
interrupted()执行后,把中断标志位置为false
小结
-
interrupt()设置中断标志位,如果有sleep(),wait()等会抛出InterruptedException
-
isInterrupted()判断中断标志位是否为true
-
interrupted()判断中断标志位是否为true,如果当为true,把中断标志位清除(置为false)
-
interrupted()是静态方法
至于深入Thread源码,暂时没空,先插个眼
参考文章
-
《Java并发编程之美》