返回顶部
首页 > 资讯 > 后端开发 > Python >Java中的interrupted()和isInterrupted()
  • 117
分享到

Java中的interrupted()和isInterrupted()

2024-04-02 19:04:59 117人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录1、前言2、api3、interrupted()和isInterrupted()区别3.1 使用方法方法一方法二1、前言 当提及如何终止一个线程时,部分读者通常立马想到的方法肯定

1、前言

当提及如何终止一个线程时,部分读者通常立马想到的方法肯定是stop(),但是stop()方法并不被推荐使用(很多规范中是禁止使用的),其原因是强制终止一个线程,会导致程序不正常的结束,会出现资源未正确释放、程序结果不正确等等问题。而是否终止一个线程应该把这个控制权转交给当前被终止的线程本身,此时采用的办法就是 ****interrupt()方法来终止,该方法相当于修改一个共享变量的值,当运行中的线程判断当前值为false则继续运行,如果有地方调用当前threadinterrupt()方法,那么这个值将变为true,此时当前线程可以根据这个值的修改来正确的终止线程的运行。

2、API

java.lang.Thread中主要提供了如下与线程中断相关的方法,其具体方法名与主要作用如下表所示。

方法名 方法作用
public void interrupt() 中断此线程
public static boolean interrupted() 测试当前线程是否被中断,该方法会恢复(清除)中断标志
public boolean isInterrupted() 测试当前线程是否被中断,该方法只会获取中断标志,不会恢复(清除)中断标志
private native boolean isInterrupted(boolean ClearInterrupted); interrupted()和isInterrupted()最终调用,该方法是native本地方法,在JVM中具体实现,也是获取线程中断标志真正调用的方法,参数ClearInterrupted意思是是否恢复(清除)中断标志

源码:




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(this);

            return;

        }

    }

    interrupt0();

}





public static boolean interrupted() {

    return currentThread().isInterrupted(true);

}





public boolean isInterrupted() {

    return isInterrupted(false);

}





private native boolean isInterrupted(boolean ClearInterrupted);





private native void interrupt0();

3、interrupted()和isInterrupted()区别

看了上述API讲述和Thread中的源码,已经清楚interrupted()isInterrupted()的主要区别了

interrupted()为静态方法,isInterrupted()为普通方法

interrupted() 返回中断标志且清除(恢复)中断标志,isInterrupted()仅返回中断标志

3.1 使用方法

我们先验证中断异常响应,通过如下两种方法的使用示例来介绍,注意Runner中的run方法的部分区别

方法一


package com.liziba.p7;

import java.util.concurrent.TimeUnit;



public class ThreadInterruptedDemo { 

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runner(), "Thread-01");

        t1.start();

        // 主线程睡眠1秒,保证t1的充分执行

        TimeUnit.SECONDS.sleep(1);

        // 发起中断

        t1.interrupt();

    }



    static class Runner implements Runnable {



        @Override

        public void run() {

            while (!Thread.currentThread().isInterrupted()) {

                System.out.println(Thread.currentThread().getName() + " is running .");

            }

        }

    }



}

输出结果:

可以看到线程在执行数次后终止运行

方法二


package com.liziba.p7;

import java.util.concurrent.TimeUnit;





public class ThreadInterruptedDemo {



    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runner(), "Thread-01");

        t1.start();

        // 主线程睡眠2秒,保证t1的充分执行

        TimeUnit.SECONDS.sleep(1);

        // 发起中断

        t1.interrupt();

    }

    static class Runner implements Runnable {



        @Override

        public void run() {

            while (!Thread.currentThread().isInterrupted()) {

                System.out.println(Thread.currentThread().getName() + " is running .");

                try {

                    // 睡眠2秒,保证主线程发起的中断能被捕获

                    TimeUnit.SECONDS.sleep(2);

                } catch (InterruptedException e) {

                    // 不对中断做任何处理,try住异常,打印

                    e.printStackTrace();

                }

            }

        }

    }



}

输出结果:

可以看到main线程中发起的t1线程中断,被捕获住异常后,未做任何处理,线程继续持续不断的运行

总结上述两种方式:

方法一和方法二,均通过判断Thread.currentThread().isInterrupted()的值来运行run方法中的逻辑,Thread.currentThread().isInterrupted()在线程未中断时返回false,当main线程中执行 t1.interrupt()时,线程t1被中断,Thread.currentThread().isInterrupted()的值变为false;在方法一中,获取到这个变化后直接结束运行;在方法二中,由于sleep()使得线程阻塞会响应中断,但是此时我仅仅catch住异常,并没有对中断做任何处理,这里有个知识点是,线程响应中断抛出异常时,会恢复(清除)中断标志,所以t1.interrupt()对中断标志的修改又被恢复了,程序仍然不断的运行。

接下来我们来验证interrupted()对于中断的标志的清除


package com.liziba.p7;



import java.util.concurrent.TimeUnit;





public class ThreadInterruptDemo2 {



    public static void main(String[] args) throws InterruptedException {



        Thread thread = new Thread(new Runner(), "Thread-1");

        thread.start();

        TimeUnit.SECONDS.sleep(2);

        thread.interrupt();

    }

    static class Runner implements Runnable {



        @Override

        public void run() {

            System.out.println(Thread.currentThread().getName() +" interrupted flag is " + Thread.currentThread().isInterrupted());



            while (!Thread.currentThread().isInterrupted()) {

                try {

                    System.out.println(Thread.currentThread().getName() + " is running .");

                    TimeUnit.SECONDS.sleep(1);

                } catch (InterruptedException e) {

                    // 响应中断,抛出异常后中断位置会被复位,自己中断自己

                    Thread.currentThread().interrupt();

                    // 这里调用isInterrupted()获取当前的中断标志

                    System.out.println(Thread.currentThread().getName()

                            +" interrupted flag is " + Thread.currentThread().isInterrupted());

                }

            }

        }

    }



}

输出结果:

这里证明interrupted()不清楚中断标志,线程在获取到 thread.interrupt()发起中断后,执行结束。

将上述catch中的Thread.currentThread().isInterrupted()修改为Thread.interrupted()再次运行


package com.liziba.p7;

import java.util.concurrent.TimeUnit;





public class ThreadInterruptDemo2 {





    public static void main(String[] args) throws InterruptedException {



        Thread thread = new Thread(new Runner(), "Thread-1");

        thread.start();

        TimeUnit.SECONDS.sleep(2);

        thread.interrupt();

    }



    // 区别在catch中

    static class Runner implements Runnable {



        @Override

        public void run() {

            System.out.println(Thread.currentThread().getName() +" interrupted flag is " + Thread.currentThread().isInterrupted());

            while (!Thread.currentThread().isInterrupted()) {

                try {

                    System.out.println(Thread.currentThread().getName() + " is running .");

                    TimeUnit.SECONDS.sleep(1);

                } catch (InterruptedException e) {

                    // 响应中断,抛出异常后中断位置会被复位,自己中断自己

                    Thread.currentThread().interrupt();

                    // 注意区别在这里

                    System.out.println(Thread.currentThread().getName()

                            +" interrupted flag is " + Thread.interrupted());

                }

            }

        }

    }



}

输出结果:

线程也响应到了 thread.interrupt()的中断,但是由于catch中调用了Thread.interrupted(),对中断标志进行了清除,所以!Thread.currentThread().isInterrupted()判断仍然等于true,线程继续不断的运行

看到这里,应该已经理解了这两个方法的主要区别和其使用,最后我们来看下一个源码中的使用案例。我们通过观看AbstractQueuedSynchronizer(AQS)中的await()方法,来看其在源码中的使用。


public final void await() throws InterruptedException {

    // 判断当前线程是否被中断,如果被中断则恢复中断标志

    if (Thread.interrupted())

        throw new InterruptedException();

    node node = addConditionWaiter();

    int savedState = fullyRelease(node);

    int interruptMode = 0;

    while (!isOnSyncQueue(node)) {

        LockSupport.park(this);

        if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)

            break;

    }

    if (acquireQueued(node, savedState) && interruptMode != THROW_IE)

        interruptMode = REINTERRUPT;

    if (node.nextWaiter != null) // clean up if cancelled

        unlinkCancelledWaiters();

    if (interruptMode != 0)

        reportInterruptAfterWait(interruptMode);

}

AbstractQueuedSynchronizer(AQS)源码中使用静态Thread.interrupted(),判断当前线程是否被中断,并恢复中断标志,如果线程已被中断则抛出InterruptedException中断异常。清除标志位的作用就是为了当前线程响应过中断后,再次进入的时候可以进行后续操作。

到此这篇关于Java中的interrupted()isInterrupted()的文章就介绍到这了,更多相关interrupted()和isInterrupted()内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java中的interrupted()和isInterrupted()

本文链接: https://lsjlt.com/news/158350.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java中的interrupted()和isInterrupted()
    目录1、前言2、API3、interrupted()和isInterrupted()区别3.1 使用方法方法一方法二1、前言 当提及如何终止一个线程时,部分读者通常立马想到的方法肯定...
    99+
    2024-04-02
  • java中isInterrupted()怎么判断线程
    这篇文章给大家分享的是有关java中isInterrupted()怎么判断线程的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Java的优点是什么1. 简单,只需理解基本的概念,就可以编写适合于各种情况的应用程序;...
    99+
    2023-06-14
  • java isInterrupted()判断线程的实例讲解
    1、说明 isInterrupted()可以判断当前线程是否被中断,仅仅是对interrupt()标识的一个判断,并不会影响标识发生任何改变(因为调用interrupt()的时候会设...
    99+
    2024-04-02
  • 如何在java中使用isInterrupted()函数判断线程
    这期内容当中小编将会给大家带来有关如何在java中使用isInterrupted()函数判断线程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java有哪些集合类Java中的集合主要分为四类:1、List...
    99+
    2023-06-14
  • Java中的equsals和==
    目录Java的equsals和==1、Java 中的==2、Java 中equals方法Java的equsals和== 前言:在我们常用的类中equals被重写后,作用就是为了比较...
    99+
    2024-04-02
  • JAVA和MySQL中的锁
    1.锁的作用         首先先来了解一下我们为什么要使用到锁,我们都知道现在的计算机系统内部采用的都是多线程的处理方式,而且在我们自己设计的一些系统和数据库并发访问之中也会使用到多线程,那我们如何保证当多个线程访问一些数据时这些数据是...
    99+
    2023-09-14
    mysql 数据库
  • Java中的print()和println()
    目录1、print() 2、println()3、print() 和 println() 的区别1、print()  print() :Java 中的 print() 方法用于在控制...
    99+
    2024-04-02
  • Java中的abstract和interface
    目录1、简介2、准则2.1 接口优先于抽象类2.2 接口中不应该实现方法2.3 接口不应该用于导出常量 1、简介 abstract和interface关键字在Java中随处可见,它是...
    99+
    2024-04-02
  • java中HashMap和LinkedHashMap的区别
    HashMaphashMap是最常用的Map,根据键的HashCode值存储数据,可以根据键直接获取它的值,具有很快的访问速度,遍历时候的顺序是完全随机的。HashMap只允许一个键为Null,允许多个值为Null。特性: 完全随机优点: ...
    99+
    2019-03-31
    java HashMap LinkedHashMap 区别
  • java中栈和堆的区别
    在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分: (推荐学习:java课程)Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区...
    99+
    2021-03-03
    java入门 java
  • java中print和println的区别
    printprintln的区别 (推荐学习:java课程)print将它的参数显示在命令窗口,并将输出光标定位在所显示的最后一个字符之后。println 将它的参数显示在命令窗口,并在结尾加上换行符,将输出光标定位在下一行的...
    99+
    2017-03-18
    java入门 java
  • java中comparable和comparator的区别
    确定两个对象之间的大小关系及排列顺序称为比较,能实现这个比较功能的类或方法称之为比较器,在java中有两种比较器。内部比较器(Comparable接口)和外部比较器(Comparator接口)一、比较器排序Comparator的使用——可以...
    99+
    2015-02-01
    java comparable comparator 区别
  • java中int和Integer的区别
    java中int和Integer的区别:类型不同,int是数据类型,而integer是引用类型。int存储的是数值,integer存储的是引用对象的地址。integer对象会占用更多的内存,而int占用的空间少。Integer变量与int变...
    99+
    2024-04-02
  • Java中?extendsT和?superT的理解
    目录 通配符类型上界< extends T>不能往里存,只能往外取下界< super T>不影响往里存,但往外取只能放在Object对象里PECS原则总结 通...
    99+
    2024-04-02
  • Java中NoClassDefFoundError 和 ClassNotFoundException的区别
    目录NoClassDefFoundErrorClassNotFoundException解决办法前言: 从类继承层次上来看,ClassNotFoundException是从Exce...
    99+
    2024-04-02
  • Java中的输入和输出
    Java中的输入和输出是非常重要的,可以让程序与用户进行交互,读取和写入数据。下面是一些Java输入和输出的常用知识总结: 1. 标准输入输出(System.in和System.out): - 标准输入(System.in)是指从键盘或控制...
    99+
    2023-09-29
    javascript 开发语言 ecmascript
  • Java中ReentrantLock和ReentrantReadWriteLock的原理
    目录ReentrantLock 原理概念核心变量和构造器核心方法ReentrantReadWriteLock 原理用例核心变量和构造器Sync类tryAcquire获取写锁的流程tr...
    99+
    2024-04-02
  • Java中的Comparable和Comparator接口
    目录一. Comparable接口1. Comparable简介2. 为什么要实现Comparable接口3. Comparable的实际应用二. Comparator接口1. Co...
    99+
    2024-04-02
  • Java中stream.map和stream.forEach的区别
    目录什么是 stream 流stream.map 和 stream.forEach 的区别网上很多关于讲解这俩个区别的文章,但大多数要么不明不白,要么太复杂难理解。所以自己通俗的讲一...
    99+
    2022-11-13
    Java stream.map Java stream.forEach Java stream.map和stream.forEach
  • Java 中的 this 和 super 区别
    目录1、简介2、引子2.1 父类中声明无参构造函数2.2 子类显示的通过super调用父类的有参构造函数3、this4、super 5、总结5.1 对比差异 5.2 相同点 5.3 ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作