JUC并发编程-中断机制

2024-08-23 09:04
文章标签 并发 编程 中断 机制 juc

本文主要是介绍JUC并发编程-中断机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.中断协商机制

线程不应该由其他线程来强制中断或暂停,应该由线程自己自行停止。这意味着Thead.stop,Thead.suspend,Thead.resume都已经被废弃。

在Java中没有办法立即停止一条线程,然而停止线程尤为重要,例如取消一个耗时的操作。

因此,Java提供一种用于停止线程的协商机制(中断),中断标识协商机制。

中断是一种协商机制,Java没有给中断添加任何语法,中断的过程完全由程序员自己实现。

如果想中断一个线程,可以手动调用interrupt方法,该方法也仅仅将线程对象的中断标识设置为true,接着你需要写代码不断检查当前线程的标识位,如果为true,则表示别的线程请求该线程中断。

每个线程对象都有一个中断标识位,用于表示线程是否被中断,该标识位为true表示中断,标识位为false表示未中断;通过调用线程对象的interrupt方法将线程标识位设置为true。既可以在别的线程中调用,也可以在自己的线程中调用。

2. 中断3大方法

  • interrupt():当调用某个线程的 interrupt() 方法时,该线程的中断状态将被设置为 true。如果该线程当前被 Object.wait()Thread.join() 或 Thread.sleep() 方法阻塞,那么线程的中断状态将被清除,并且线程将接收到一个 InterruptedException。如果该线程在运行中且没有阻塞在这些方法上,那么中断状态将被设置,但线程将继续运行,除非它定期检查中断状态。
  • interrupted()用于检查当前线程是否已被中断,并清除当前线程的中断状态。如果当前线程的中断状态被设置,则返回 true,并且在返回前清除中断状态。
  • isInterrupted():它用于检查调用此方法的线程是否已被中断。如果线程的中断状态被设置,则返回 true,否则返回 false。此方法不会清除线程的中断状态。

3. 通过volatile实现线程中断停止

public class VolatileInterruptExample {// 使用volatile关键字确保可见性private static volatile boolean running = true;public static void main(String[] args) throws InterruptedException {Thread workerThread = new Thread(() -> {while (running) {// 执行任务...System.out.println("线程正在运行...");// 为了演示,我们在这里加入一个简单的延时try {Thread.sleep(1000);} catch (InterruptedException e) {// 当线程被中断时,通常会抛出InterruptedException// 在这里我们可以选择退出循环,也可以选择其他逻辑System.out.println("线程被中断,退出循环");break;}}System.out.println("线程已停止");});// 启动线程workerThread.start();// 主线程暂停一段时间,然后设置running为false来停止工作线程Thread.sleep(3500);running = false;// 等待工作线程结束workerThread.join();System.out.println("主线程结束");}
}
  • 我们定义了一个volatile布尔变量running,它用来控制工作线程的执行。
  • 工作线程在它的run方法中运行一个循环,循环的条件是runningtrue
  • 在主线程中,我们让工作线程运行一段时间后,通过将running设置为false来停止工作线程。
  • 工作线程在检测到running变为false后,会退出循环并结束运行。

volatile关键字确保了running变量的改变对所有线程立即可见,这是实现线程安全的一个重要特性。当主线程修改running的值时,工作线程能够立即看到这个变化,从而正确地响应停止信号。

4. 通过AutomicBoolean实现线程中断停止

AtomicBoolean 提供了原子操作布尔值的方法。使用 AtomicBoolean 可以安全地在多个线程之间共享一个布尔值

import java.util.concurrent.atomic.AtomicBoolean;public class AtomicBooleanInterruptExample {// 使用AtomicBoolean来确保线程安全private static AtomicBoolean running = new AtomicBoolean(true);public static void main(String[] args) throws InterruptedException {Thread workerThread = new Thread(() -> {while (running.get()) {// 执行任务...System.out.println("线程正在运行...");// 为了演示,我们在这里加入一个简单的延时try {Thread.sleep(1000);} catch (InterruptedException e) {// 当线程被中断时,通常会抛出InterruptedExceptionSystem.out.println("线程被中断,退出循环");break;}}System.out.println("线程已停止");});// 启动线程workerThread.start();// 主线程暂停一段时间,然后设置running为false来停止工作线程Thread.sleep(3500);running.set(false);// 等待工作线程结束workerThread.join();System.out.println("主线程结束");}
}

  • 我们创建了一个 AtomicBoolean 类型的 running 变量,并初始化为 true
  • 工作线程在它的 run 方法中运行一个循环,循环的条件是 running.get() 返回 true
  • 在主线程中,我们让工作线程运行一段时间后,通过调用 running.set(false) 来停止工作线程。
  • 工作线程在检测到 running 变为 false 后,会退出循环并结束运行。

AtomicBoolean 的 get 和 set 方法保证了操作的原子性,这意味着在多线程环境中,这些操作不会被其他线程中断,从而保证了线程安全。这是 AtomicBoolean 优于普通布尔变量的一个重要方面。使用 AtomicBoolean,我们不需要担心可见性和原子性问题,因为它内部已经处理了这些问题。

5. 通过interrupt实现线程中断

在需要中断单点线程中不断监听中断状态,一旦发生中断,就执行相应中断处理业务逻辑停止线程。

public class InterruptExample {public static void main(String[] args) throws InterruptedException {// 创建一个线程Thread workerThread = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {// 执行任务...System.out.println("线程正在运行...");// 模拟耗时操作try {Thread.sleep(1000);} catch (InterruptedException e) {// 在这里捕获InterruptedException异常// 这通常是我们想要中断线程的地方System.out.println("线程在sleep期间被中断");// 由于中断状态被清除,我们需要重新设置中断状态Thread.currentThread().interrupt();// 选择退出循环或者进行其他清理工作break;}}System.out.println("线程已停止");});// 启动线程workerThread.start();// 主线程暂停一段时间,然后中断工作线程Thread.sleep(3500);workerThread.interrupt();// 等待工作线程结束workerThread.join();System.out.println("主线程结束");}
}
  • 我们创建了一个工作线程,它在一个循环中执行任务,并在每次迭代后调用Thread.sleep(1000)来模拟耗时操作。
  • 循环的条件是!Thread.currentThread().isInterrupted(),这意味着如果线程的中断状态被设置,循环将终止。
  • 当工作线程在sleep期间被中断时,会抛出InterruptedException。在catch块中,我们捕获了这个异常。
  • 在捕获InterruptedException后,我们通过调用Thread.currentThread().interrupt()重新设置了线程的中断状态,因为在抛出InterruptedException后,中断状态会被清除。
  • 我们选择退出循环,这样线程就可以执行任何必要的清理操作,然后退出。

6. 中断协商深度解析

(1)调用 interrupt() 时,如果线程处于正常活动状态,会将线程的中断标识设置为true,被设置中断标识的线程将继续正常运行,不受影响。

(2)中断不活动的线程不会产生任何影响,使用interrupt后,isInterrupted的结果为false

(3)线程处于阻塞状态,在别的线程中调用当前线程的interrupt方法,那么线程将立即退出被阻塞的状态,并抛出一个InterruptedException异常。

这篇关于JUC并发编程-中断机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1098943

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

高并发环境中保持幂等性

在高并发环境中保持幂等性是一项重要的挑战。幂等性指的是无论操作执行多少次,其效果都是相同的。确保操作的幂等性可以避免重复执行带来的副作用。以下是一些保持幂等性的常用方法: 唯一标识符: 请求唯一标识:在每次请求中引入唯一标识符(如 UUID 或者生成的唯一 ID),在处理请求时,系统可以检查这个标识符是否已经处理过,如果是,则忽略重复请求。幂等键(Idempotency Key):客户端在每次

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow

【Tools】大模型中的自注意力机制

摇来摇去摇碎点点的金黄 伸手牵来一片梦的霞光 南方的小巷推开多情的门窗 年轻和我们歌唱 摇来摇去摇着温柔的阳光 轻轻托起一件梦的衣裳 古老的都市每天都改变模样                      🎵 方芳《摇太阳》 自注意力机制(Self-Attention)是一种在Transformer等大模型中经常使用的注意力机制。该机制通过对输入序列中的每个元素计算与其他元素之间的相似性,

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念