首页 > 代码库 > 中断机制

中断机制

中断机制

java没有提供一种安全的直接的方法来停止某个线程,而是提供了中断机制。中断机制是一种协作机制,也就是说通过中断并不能直接终止另一个线程,而需要被中断的线程自己吃力。每一个线程对象里有一个标识位标识是否有中断请求,代表着是否有中断请求。

 

三个中断相关方法

1.interrupt

 1  public void interrupt() {
 2         if (this != Thread.currentThread())
 3             checkAccess();
 4 
 5         synchronized (blockerLock) {
 6             Interruptible b = blocker;
 7             if (b != null) {
 8                 interrupt0();           // Just to set the interrupt flag
 9                 b.interrupt(this);
10                 return;
11             }
12         }
13         interrupt0();
14     }
private native void interrupt0();

第8行注释说的很清楚,仅仅是设置中断标识位,这是一个native方法。

 

2.isInterrupted  这是个实例方法

方法是测试线程是否中断,中断标识位的状态并不受到该方法的信息。也是一个native方法。

3.interrupted  这是个静态方法

方法是测试当前线程是否中断,线程中断标识位会清除。也是native方法。

 

作为一种协作机制,不会强求被标记中断的线程一定要在某个点进行中断处理,实际上,被中断的线程只需要在合适的时候处理,如果没有合适的时间,也可以不处理。频繁的检查中断可能会导致程序执行效率的低下,较少的检查会导致中断请求得不得及时响应。实际场景中,

如果性能指标比较关键,可能需要建立一个测试模型来分析最佳的中断检测点,以平衡性能和响应灵敏性。

 

 

 

线程中断举例

 1 public static void main(String[] args) throws Exception {
 2         Runnable runnable = new Runnable() {
 3             public void run() {
 4                 while (true) {
 5                     if (Thread.currentThread().isInterrupted()) {
 6                         System.out.println("线程被中断了");
 7                         return;
 8                     } else {
 9                         System.out.println("线程没有被中断");
10                     }
11                 }
12             }
13         };
14         Thread t = new Thread(runnable);
15         t.start();
16         Thread.sleep(3000);
17         t.interrupt();
18         System.out.println("线程中断了,程序到这里了");
19     }

结果

...
线程没有被中断
线程没有被中断
线程没有被中断
线程没有被中断
线程没有被中断
线程中断了,程序到这里了
线程被中断了

代码分为以下几步:

1、main函数起一个t线程

2、main函数3秒钟之后给t线程打一个中断标识位,表示t线程要中断

3、t线程无限轮询自己的中断标识位,中断了则打印、退出,否则一直运行

从控制台上打印的语句看到,3秒钟中断后,打印出该打印的语句后,就停止了。那这种场景就是前面说的"频繁地检查",导致程序效率低下;那如果不频繁地检查呢,比如在while中的else分支中加上Thread.sleep(500),表示500ms即0.5s检查一次,那这种场景就是前面说的"中断得不到及时的响应"。

其实这个例子中,t线程完全可以不用去管这个中断标识位的,不去检查就好了,只管做自己的事情,这说明中断标识位设不设置是别人的事情,处不处理是我自己的事情,没有强制要求必须处理中断。

但是,那些会抛出InterruptedException的方法要除外。像sleep、wait、notify、join,这些方法遇到中断必须有对应的措施,可以直接在catch块中处理,也可以抛给上一层。这些方法之所以会抛出InterruptedException就是由于Java虚拟机在实现这些方法的时候,本身就有某种机制在判断中断标识位,如果中断了,就抛出一个InterruptedException。

 

中断机制