java中使用interrupt通知线程停止详析

Java中使用interrupt通知线程停止详析

概述

在Java多线程编程中,有时候需要在某个条件满足时中断线程的执行。Java中提供了一种机制,即通过中断(interrupt)的方式通知线程停止。本文将详细阐述Java中使用interrupt通知线程停止的完整攻略。

了解中断机制

在Java中,线程有一个boolean类型的中断标记,初始值为false。当线程调用了interrupt()方法时,中断标记就会被设置为true,表示该线程收到了中断信号。线程在被中断时,可以通过isInterrupted()方法检查中断标记是否被设置了。

如何停止线程

有两种方式停止线程,分别是:

  1. 使用中断(interrupt)机制

    在线程中处理中断信号,以此来停止线程。比如,在线程中不断地检查中断标记,一旦中断标记为true,就立即结束线程。

  2. 使用共享变量

    在线程外部设置一个共享变量,在满足某个条件时,将变量值设置为true。线程在执行时不断检查共享变量的值,如果发现变量值为true,就立即结束线程。

如何使用中断机制停止线程

1. 在线程中检测中断标记

在线程中处理中断信号最常见的方式是不断地检查中断标记,一旦标记为true,就立即结束线程。

public class MyThread extends Thread {
    public void run() {
        while(!isInterrupted()) {
            // do something
        }
    }
}

上面的代码中,线程不断地执行某个任务,同时在每次循环开始时检查中断标记,如果标记为true,则立即退出线程。如果不检查中断标记,那么线程将不会被停止。

2. 在sleep、wait等阻塞方法中捕获中断异常

在使用阻塞方法(如sleep、wait等)时,也可以使用中断机制停止线程。当线程处于sleep、wait等阻塞状态时,调用线程的interrupt()方法将会导致线程抛出InterruptedException异常,从而使线程提前退出阻塞状态。

public class MyThread extends Thread {
    public void run() {
        try {
            while(!isInterrupted()) {
                // do something
                Thread.sleep(1000); // 使用阻塞方法
            }
        } catch (InterruptedException e) {
            // 处理中断异常
        }
    }
}

上面的代码中,线程在循环过程中使用了sleep阻塞方法。由于线程处于阻塞状态,无法在循环中检查中断标记。因此,当线程收到中断信号时,会抛出InterruptedException异常,从而使线程提前退出阻塞状态,进而继续执行线程中的循环所在位置的代码。需要注意的是,抛出InterruptedException异常也清除线程的中断状态。

示例说明

示例一

public class ThreadInterruptDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    System.out.println("线程正在运行...");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        break;
                    }
                }
                System.out.println("线程结束");
            }
        });
        t.start();

        Thread.sleep(5000);
        t.interrupt();
    }
}

上述示例中,主线程创建了一个新线程t,并启动该线程。在新线程t中使用while循环不断输出一行“线程正在运行…”,并使用Thread.sleep()方法暂停1秒钟,从而模拟线程正在工作。

在主线程休眠5秒钟后,调用新线程t的interrupt()方法,线程t会收到中断信号,终止循环并输出“线程结束”。这说明通过使用中断机制,能够实现对线程的安全停止。

示例二

public class ThreadInterrupt2Demo {
    public static void main(String[] args) throws InterruptedException {
        ThreadCounter counter = new ThreadCounter();
        Thread t1 = new Thread(counter, "Thread-1");
        Thread t2 = new Thread(counter, "Thread-2");
        t1.start();
        t2.start();

        Thread.sleep(5000);
        t1.interrupt();
        t2.interrupt();
    }

    private static class ThreadCounter implements Runnable {
        @Override
        public void run() {
            int count = 0;
            while (!Thread.currentThread().isInterrupted() && count < 5) {
                count++;
                System.out.println(Thread.currentThread().getName() + ": " + count);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt(); // 重新设置中断标志
                }
            }
            System.out.println(Thread.currentThread().getName() + "结束");
        }
    }
}

上述示例中,主线程创建了两个新线程t1和t2,并启动这两个线程。线程t1和t2都执行一个Runnable接口实现类ThreadCounter的代码逻辑,主要是在循环中不断输出线程名称和计数器的数值,并使用Thread.sleep()方法暂停1秒钟,从而模拟线程正在工作,计数器的默认初始值为0。

在主线程休眠5秒钟后,调用线程t1和t2的interrupt()方法,线程t1和t2将会收到中断信号,并尝试重新设置自己的中断标记,从而安全终止循环输出线程结束信息。

需要注意的是,由于在线程t1和t2中捕获InterruptedException异常而重新设置中断标记,因此在重新设置中断标记后,循环中使用Thread.sleep()方法时就可能再次触发InterruptedException异常,所以需要再次调用interrupt()方法来设置自己的中断标记。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java中使用interrupt通知线程停止详析 - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • Spring boot2.0 日志集成方法分享(1)

    Spring Boot2.0 日志集成方法分享(1) 在Spring Boot2.0中,我们可以使用多种方式来集成日志框架,如Logback、Log4j2、Java Util Logging等。本文将详细讲解Spring Boot2.0日志集成方法的完整攻略,并提供两个示例。 1. 集成Logback 以下是集成Logback的基本流程: 在pom.xml文…

    Java 2023年5月15日
    00
  • Spring Boot实战之模板引擎

    SpringBoot实战之模板引擎 模板引擎是用于生成动态HTML内容的工具,它将模板文件和数据进行结合,生成最终的HTML文档,常见的模板引擎有Thymeleaf、FreeMarker、Velocity等。在SpringBoot框架中,可以非常方便地集成各种模板引擎,本文将重点介绍如何使用Thymeleaf和FreeMarker模板引擎。 Thymelea…

    Java 2023年5月15日
    00
  • Tomcat如何监控并删除超时Session详解

    要实现Tomcat监控并删除超时的Session,我们需要进行以下步骤: 在tomcat的web.xml文件中添加以下配置: <session-config> <session-timeout>30</session-timeout> </session-config> 该配置表示Session的超时时间为30…

    Java 2023年6月15日
    00
  • 三种Java打印PDF文档的实例代码

    接下来我将为您详细讲解“三种Java打印PDF文档的实例代码”的完整攻略。 1. 使用Java本身的打印功能 Java本身提供了一些打印功能,可以帮助我们打印PDF文档。下面是使用Java本身的打印功能的示例代码: import java.awt.print.PrinterJob; import javax.print.PrintService; impor…

    Java 2023年5月19日
    00
  • spring boot tomcat jdbc pool的属性绑定

    关于“spring boot tomcat jdbc pool的属性绑定”的完整攻略,我可以从以下几个方面进行讲解: 引入依赖 首先,我们需要在pom.xml文件中引入相关的依赖,在该文件中添加如下内容: <dependency> <groupId>org.springframework.boot</groupId> &l…

    Java 2023年5月19日
    00
  • Spring Data JPA实现审计功能过程详解

    下面我将详细讲解“Spring Data JPA实现审计功能过程详解”的完整攻略,具体步骤如下: 第一步:添加依赖 在pom.xml文件中添加以下依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boo…

    Java 2023年5月20日
    00
  • Spring Boot 整合 Thymeleaf 实例分享

    下面是 Spring Boot 整合 Thymeleaf 实例分享的完整攻略。 什么是Spring Boot和Thymeleaf Spring Boot是Spring框架的一款快速开发框架,可以快速搭建一个基础的web应用 Thymeleaf是一款非常流行的模板引擎,可以将数据渲染成HTML页面,使用简单,容易上手 如何整合Spring Boot和Thyme…

    Java 2023年5月20日
    00
  • Spring Boot定时+多线程执行过程解析

    关于“Spring Boot定时+多线程执行过程解析”的完整攻略,我会与你分享以下几个方面的内容: Spring Boot定时任务的基本概念 Spring Boot多线程的基本概念 定时任务和多线程联合应用的实现思路 示例说明 1. Spring Boot定时任务的基本概念 Spring Boot提供了强大的定时任务功能,其核心是使用Scheduled注解。…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部