java中线程中断的实现示例

 更新时间:2023年09月07日 09:03:30   作者:Michael_lcf  
中断只是一种协作协商机制,Java没有给中断增加任何语法,中断的过程完全需要程序员自己实现,本文就来介绍一下线程中断的实现,具有一定的参考价值,感兴趣的可以了解一下

1、线程中断 即 线程的取消/关闭的机制

Java中停止一个线程的主要机制是中断,中断并不是强迫终止一个线程,它是一种 协作机制 ,是给线程传递一个取消/关闭信号,由线程自身来决定如何以及何时退出。

停止线程,但这个方法被标记为了过时。
@Deprecated
public final void stop()
=========================
返回对应线程的中断标志位是否为true。
public boolean isInterrupted()
返回当前线程的中断标志位是否为true,并清空中断标志位。
public static boolean interrupted()
表示中断对应的线程。
public void interrupt()

2、线程对中断interrupt()的反应

2.1、RUNNABLE:线程在运行或具备运行条件只是在等待操作系统调度

举个栗子:

public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(() -> {
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("线程t 执行中...");
        }
    });
    t.start();
    Thread.sleep(1);
    t.interrupt();
    System.out.println("main exit");
}

RUNNABLE状态的线程tinterrupt()后,是否终止中断线程由线程t自身代码逻辑决定。

2.2、WAITING/TIMED_WAITING:线程在等待某个条件或超时

线程执行如下方法会进入WAITING状态:
public final void join() throws InterruptedException
public final void wait() throws InterruptedException
线程执行如下方法会进入TIMED_WAITING状态:
public final native void wait(long timeout) throws InterruptedException
public static native void sleep(long millis) throws InterruptedException
public final synchronized void join(long millis) throws InterruptedException

举个栗子:

public class ThreadInterrupt {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                System.out.println("Thread.interrupted() = " + Thread.interrupted());
                //Thread.interrupted() = false
                System.out.println("Thread.interrupted() = " + Thread.interrupted());
                //Thread.interrupted() = false
            }
        });
        t.start();
        t.interrupt();
    }
}

捕获到InterruptedException,通常表示希望结束该线程,线程大概有两种处理方式:
向上传递该异常,这使得该方法也变成了一个可中断的方法,需要调用者进行处理。

有些情况,不能向上传递异常,比如Thread的run方法,它的声明是固定的,不能抛出任何受检异常,这时,应该捕获异常,进行合适的清理操作,清理后,一般应该调用Thread的interrupt方法设置中断标志位,使得其他代码有办法知道它发生了中断。

2.3、BLOCKED:线程在等待锁,试图进入同步块

举个栗子:

public class ThreadInterrupt {
    private final static Object lockObj = new Object();
    private static class MyBlockedThread extends Thread {
        @Override
        public void run() {
            System.out.println("MyBlockedThread.run = " + Thread.currentThread().isInterrupted());
            synchronized (lockObj) {
                while (!Thread.currentThread().isInterrupted()) {
                    System.out.println(Thread.currentThread().isInterrupted());
                }
            }
            System.out.println("exit");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        synchronized (lockObj) {
            MyBlockedThread myBlockedThread = new MyBlockedThread();
            myBlockedThread.start();
            Thread.sleep(3000);
            myBlockedThread.interrupt();
            myBlockedThread.join(); // join方法会等待线程执行完后返回
        }
    }
}

myBlockedThread.join();该行代码放开注释掉情况下:线程一直等待锁 BLOCKED。

com.michael.ThreadInterrupt.MyBlockedThread.run = false

myBlockedThread.join();该行代码注释掉情况下:因为主线程不再等待线程myBlockedThread结束,释放锁lock后,线程myBlockedThread会获得锁,然后检测到发生了中断,然后程序退出。

com.michael.ThreadInterrupt.MyBlockedThread.run = false
exit

2.4、NEW/TERMINATED:线程还未启动或已结束

举个栗子:

public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(() -> {
        System.out.println("线程t 执行...");
    });
    t.interrupt();
    System.out.println("NEW = " + t.isInterrupted());
    t.start();
    Thread.sleep(100);
    t.interrupt();
    System.out.println("TERMINATE = " + t.isInterrupted());
}
============ 执行结果 ============
NEW = false
线程t 执行...
TERMINATE = false

2.5、IO操作

如果线程在等待IO操作,尤其是网络IO,则会有一些特殊的处理。

  • 如果IO通道是可中断的,即实现了InterruptibleChannel接口,则线程的中断标志位会被设置,同时线程会收到异常ClosedByInterruptException
  • 如果线程阻塞于Selector调用,则线程的中断标志位会被设置,同时阻塞的调用会立即返回。
  • InputStream的read调用,该操作是不可中断的,如果流中没有数据,read会阻塞 (但线程状态依然是RUNNABLE),且不响应interrupt(),与synchronized类似,调用interrupt()只会设置线程的中断标志,而不会真正"中断"。

3、关于中断的经验

Java中取消/关闭线程技术是中断,但它是一种协作机制,不会强制终止线程。线程在不同状态IO操作时对中断的反应有所不同。
作为线程的实现者:应该提供明确的取消/关闭方法,并用文档描述清楚其行为。
作为线程的调用者:应该使用其取消/关闭方法,而不是贸然调用interrupt()方法。

到此这篇关于java中线程中断的实现示例的文章就介绍到这了,更多相关java 线程中断内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决idea打包成功但是resource下的文件没有成功的问题

    解决idea打包成功但是resource下的文件没有成功的问题

    这篇文章主要介绍了解决idea打包成功但是resource下的文件没有成功的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • 如何基于Autowired对构造函数进行注释

    如何基于Autowired对构造函数进行注释

    这篇文章主要介绍了如何基于Autowired对构造函数进行注释,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Java中对象初始化顺序的详细介绍

    Java中对象初始化顺序的详细介绍

    在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,网上关于Java中对象初始化顺序的文章很多,这篇文章我们将详细介绍Java中对象初始化顺序。有需要的可以参考学习。
    2016-10-10
  • Java内存模型知识详解

    Java内存模型知识详解

    这篇文章主要介绍了Java内存模型知识详解,文中通过对内存访问时的交互关系图解介绍的十分详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Java聊天室之实现客户端一对一聊天功能

    Java聊天室之实现客户端一对一聊天功能

    这篇文章主要为大家详细介绍了Java简易聊天室之实现客户端一对一聊天功能,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以了解一下
    2022-10-10
  • java中this的用法示例(关键字this)

    java中this的用法示例(关键字this)

    这篇文章主要介绍了java中this的用法示例(关键字this),需要的朋友可以参考下
    2014-03-03
  • java socket实现局域网聊天

    java socket实现局域网聊天

    这篇文章主要为大家详细介绍了java socket实现局域网聊天,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Tomcat 多端口 多应用

    Tomcat 多端口 多应用

    当你使用Tomcat作为Web Server的时候,是不是会想过这样的一个问题:如何利用Tomcat建立两个Web Server,同时侦听来自不同端口的请求呢?要实现这一点是很简单的。以下假设Tomcat安装在D:/Tomcat5.0目录下。
    2008-02-02
  • Java实现JSON与XML相互转换的简明教程

    Java实现JSON与XML相互转换的简明教程

    Java实现复杂数据结构(如嵌套对象、数组)在 JSON 与 XML 之间的相互转换,可以使用 Jackson 和 Jackson XML 扩展库来完成,Jackson 是一个流行的 JSON 处理库,通过 Jackson 的 XML 扩展库,可以实现 JSON 和 XML 之间的转换,需要的朋友可以参考下
    2024-08-08
  • Java中使用阻塞队列控制线程集实例

    Java中使用阻塞队列控制线程集实例

    这篇文章主要介绍了Java控制阻塞队列线程集实例,本文用一个程序展示了如何使用阻塞队列来控制线程集,程序功能是在一个目录及它的所有子目录下搜索所有文件,打印出包含指定关键字的文件列表,需要的朋友可以参考下
    2015-01-01

最新评论