下面的这断代码大家应该再熟悉不过了,线程休眠需要捕获或者抛出线程中断异常,也就是你在睡觉的时候突然有个人冲进来把你吵醒了。
1
2
3
4
5
|
try { thread.sleep( 3000 ); } catch (interruptedexception e) { e.printstacktrace(); } |
此时线程被打断后,代码会继续运行或者抛出异常结束运行,这并不是我们需要的中断线程的作用。
到底是什么是线程中断?
线程中断即线程运行过程中被其他线程给打断了,它与 stop 最大的区别是:stop 是由系统强制终止线程,而线程中断则是给目标线程发送一个中断信号,如果目标线程没有接收线程中断的信号并结束线程,线程则不会终止,具体是否退出或者执行其他逻辑由目标线程决定。
我们来看下线程中断最重要的 3 个方法,它们都是来自 thread 类!
1、java.lang.thread#interrupt
中断目标线程,给目标线程发一个中断信号,线程被打上中断标记。
2、java.lang.thread#isinterrupted()
判断目标线程是否被中断,不会清除中断标记。
3、java.lang.thread#interrupted
判断目标线程是否被中断,会清除中断标记。
线程中断实战
我们来实例演示下线程中断如何用!
示例1(中断失败)
1
2
3
4
5
6
7
8
9
10
11
12
|
/** * 微信公众号:java技术栈 */ private static void test1() { thread thread = new thread(() -> { while ( true ) { thread.yield(); } }); thread.start(); thread.interrupt(); } |
请问示例1中的线程会被中断吗?答案:不会,因为虽然给线程发出了中断信号,但程序中并没有响应中断信号的逻辑,所以程序不会有任何反应。
示例2:(中断成功)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/** * 微信公众号:java技术栈 */ private static void test2() { thread thread = new thread(() -> { while ( true ) { thread.yield(); // 响应中断 if (thread.currentthread().isinterrupted()) { system.out.println( "java技术栈线程被中断,程序退出。" ); return ; } } }); thread.start(); thread.interrupt(); } |
我们给示例2加上了响应中断的逻辑,程序接收到中断信号打印出信息后返回退出。
示例3(中断失败)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/** * 微信公众号:java技术栈 */ private static void test3() throws interruptedexception { thread thread = new thread(() -> { while ( true ) { // 响应中断 if (thread.currentthread().isinterrupted()) { system.out.println( "java技术栈线程被中断,程序退出。" ); return ; } try { thread.sleep( 3000 ); } catch (interruptedexception e) { system.out.println( "java技术栈线程休眠被中断,程序退出。" ); } } }); thread.start(); thread.sleep( 2000 ); thread.interrupt(); } |
示例3 sleep() 方法被中断,并输出了 java技术栈线程休眠被中断,程序退出。 程序继续运行……为什么呢?
来看 sleep 的源码:
可以看出 sleep() 方法被中断后会清除中断标记,所以循环会继续运行。。
示例4(中断成功)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
/** * 微信公众号:java技术栈 */ private static void test4() throws interruptedexception { thread thread = new thread(() -> { while ( true ) { // 响应中断 if (thread.currentthread().isinterrupted()) { system.out.println( "java技术栈线程被中断,程序退出。" ); return ; } try { thread.sleep( 3000 ); } catch (interruptedexception e) { system.out.println( "java技术栈线程休眠被中断,程序退出。" ); thread.currentthread().interrupt(); } } }); thread.start(); thread.sleep( 2000 ); thread.interrupt(); } |
示例4全部信息输出并正常退出,只是在 sleep() 方法被中断并清除标记后手动重新中断当前线程,然后程序接收中断信号返回退出。
通过以上 4 个中断示例,相信对 java 线程中断的概念有了全面的了解。