温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java中多线程的中断机制有哪些

发布时间:2021-04-08 16:09:11 来源:亿速云 阅读:128 作者:Leah 栏目:编程语言

本篇文章为大家展示了Java中多线程的中断机制有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

1、interrupt()

public void interrupt() {
  if (this != Thread.currentThread())
    checkAccess();

  synchronized (blockerLock) {
    Interruptible b = blocker;
    if (b != null) {
    interrupt0();    // Just to set the interrupt flag
    b.interrupt();
    return;
    }
  }
  interrupt0();
  }

结果

 /* Some private helper methods */
 private native void setPriority0(int newPriority);
 private native void stop0(Object o);
 private native void suspend0();
 private native void resume0();
 private native void interrupt0();

分两部分看:

(1)第一部分的第8行注释说得很清楚了,interrupt0()方法的作用是"Just to set the interrupt flag",即方法的作用仅仅是设置中断标识位

(2)第二部分的第6行就是interrupt0()方法的原型,由于方法是被native修饰的,很明显这是一个本地方法,是Java虚拟机实现的

2、isInterrupted()

方法唯一的作用只是测试线程是否已经中断,中断标识位的状态并不受到该方法的影响,看一下Java是如何实现这个方法的:

/**
 * Tests whether this thread has been interrupted. The <i>interrupted
 * status</i> of the thread is unaffected by this method.
 *
 * <p>A thread interruption ignored because a thread was not alive 
 * at the time of the interrupt will be reflected by this method 
 * returning false.
 *
 * @return <code>true</code> if this thread has been interrupted;
 *     <code>false</code> otherwise.
 * @see   #interrupted()
 * @revised 6.0
 */
public boolean isInterrupted() {
return isInterrupted(false);
}
private native boolean isInterrupted(boolean ClearInterrupted);

注意一下第一部分的第2行和第3行,"The interrupted statis of the thread is unaffected by this method",即线程的中断状态不受到这个方法的影响。最终调用的是isInterrupted(boolean ClearInterrupted),这个方法是一个native的,看得出也是Java虚拟机实现的。方法的参数ClearInterrupted,顾名思义,清除中断标识位,这里传递false,明显就是不清除

3、interrupted()

方法的作用是测试当前线程是否已经中断,线程的中断标识位由该方法清除。换句话说,连续两次调用该方法的返回值必定是false。看一下这个方法是如何实现的:

/**
 * Tests whether the current thread has been interrupted. The
 * <i>interrupted status</i> of the thread is cleared by this method. In
 * other words, if this method were to be called twice in succession, the
 * second call would return false (unless the current thread were
 * interrupted again, after the first call had cleared its interrupted
 * status and before the second call had examined it).
 *
 * <p>A thread interruption ignored because a thread was not alive 
 * at the time of the interrupt will be reflected by this method 
 * returning false.
 *
 * @return <code>true</code> if the current thread has been interrupted;
 *     <code>false</code> otherwise.
 * @see #isInterrupted()
 * @revised 6.0
 */
public static boolean interrupted() {
return currentThread().isInterrupted(true);
private native boolean isInterrupted(boolean ClearInterrupted);

同样,第2行和第3行的注释已经写得很清楚了,"Theinterruptedstatusofthethreadisclearedbythismethod",即线程的中断状态由此方法清除。另外,interrupted()方法和isInterrupted()方法调用的是同一个native方法,无非这个方法传入的是true,表示清除中断标识位

此外,JDKAPI中有些类的方法也可能会调用中断,比如FutureTask的cancel,如果传入true则会在正在运行的异步任务上调用interrupt()方法,又如ThreadPoolExecutor中的shutdownNow方法会遍历线程池中的工作线程并调用线程的interrupt()方法。这些场景下只要代码没有对中断作出响应,那么任务将一直执行下去。

中断处理时机

这其实是一个很宽泛的、没有标注答案的话题。显然,作为一种协作机制,不会强求被中断的线程一定要在某个点进行中断处理。实际上,被中断线程只需要在合适的时候处理即可,如果没有合适的时间点,甚至可以不处理。"合适的时间点"就和业务逻辑密切相关了。

处理时机决定着程序的效率和响应的灵敏度。频繁的检查中断可能会导致程序执行效率低下,较少的检查则可能导致中断请求得不到及时响应。在实际场景中,如果性能指标比较关键,可能需要建立一个测试模型来分析最佳的中断检测点,以平衡性能和响应灵敏性。

线程中断举例

写了这么多理论,写一个例子来演示一下中断:

public static void main(String[] args) throws Exception
{
  Runnable runnable = new Runnable()
  {
    public void run()
    {
      while (true)
      {
        if (Thread.currentThread().isInterrupted())
        {
          System.out.println("线程被中断了");
          return ;
        }
        else
        {
          System.out.println("线程没有被中断");
        }
      }
    }
  };
  Thread t = new Thread(runnable);
  t.start();
  Thread.sleep(3000);
  t.interrupt();
  System.out.println("线程中断了,程序到这里了");
}

看一下运行结果:

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

代码分为以下几步:

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。

上述内容就是Java中多线程的中断机制有哪些,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI