生产问题-Java服务CPU飙升100%问题

情况回顾

最近运维同学反馈有微服务CPU飙升100%,根据dump的日志文件排查出问题所在,在这里给大家做简单的分享,希望给大家工作上可以带来帮助。

核心伪代码分析

@SneakyThrows//包装成 RuntimeException ,骗过编译器,使得调用点可以不用显示处理异常信息。
public static void main(String[] args) {ExecutorService executor = Executors.newSingleThreadExecutor();FutureTask<Boolean> futureTask = new FutureTask<Boolean>(() -> {long l = 0;for (long i1 = 0; i1 < 10_000_000_000L; i1++) {l++;if (i1%1_000_000_000 == 0) {System.out.println("l = " + l);}}System.out.println("futureTask running end!");return true;});executor.execute(futureTask);try {futureTask.get(3, TimeUnit.SECONDS);// 3秒钟没结束直接关闭进程} catch (Exception e) {e.printStackTrace();futureTask.cancel(true);// 终止任务} finally {executor.shutdown();// 优雅关闭线程}System.out.println("main end");TimeUnit.SECONDS.sleep(20);
}

代码说明:实际的业务场景是在for循环里面做业务逻辑,尝试用 futureTask.get(3, TimeUnit.SECONDS) 获取任务执行结果,设置最多等待 3 秒。如果任务在这段时间之内没有执行完成,则会抛出异常。在尝试等待结果期间,如果超过 3 秒或其他异常发生,异常会被捕获,打印堆栈跟踪信息,并且尝试通过 futureTask.cancel(true) 方法来取消任务(参数 true 表示如果任务正在运行可以中断它)

CPU持续飙升原因

futureTask.cancel(true); 是Java并发API中取消一个正在执行的任务的方法调用,并不会中断线程,而且会给线程打上INTERRUPTED的标志,运行到线程可中断的节点时,线程会查看这个标志,发现是INTERRUPTED,则会close调线程。这里虽然用futureTask.cancel(true)来终止任务,线程依旧在运行,无法进行终止,一直在循环执行业务,所以CPU会持续飙升。如下:
在这里插入图片描述

解决方案

在任务里面加入线程中断点sleep(1ms)
在这里插入图片描述

@SneakyThrows//包装成 RuntimeException ,骗过编译器,使得调用点可以不用显示处理异常信息。
public static void main(String[] args) {ExecutorService executor = Executors.newSingleThreadExecutor();FutureTask<Boolean> futureTask = new FutureTask<Boolean>(() -> {long l = 0;for (long i1 = 0; i1 < 10_000_000_000L; i1++) {l++;if (i1%1_000_000_000 == 0) {TimeUnit.MILLISECONDS.sleep(1);System.out.println("l = " + l);}}System.out.println("futureTask running end!");return true;});executor.execute(futureTask);try {futureTask.get(3, TimeUnit.SECONDS);// 3秒钟没结束直接关闭进程} catch (Exception e) {e.printStackTrace();futureTask.cancel(true);// 终止任务} finally {executor.shutdown();// 优雅关闭线程}System.out.println("main end");TimeUnit.SECONDS.sleep(20);
}

在这段代码中,加上TimeUnit.MILLISECONDS.sleep(1); 会触发中断检查TimeUnit.MILLISECONDS.sleep(1); 是一个可能抛出 InterruptedException 的阻塞操作。当 sleep 方法检测到线程的中断状态被设置时,它会响应这个中断:

  1. 清除线程的中断状态(即将其重置为未中断)。
  2. 抛出 InterruptedException,表示线程被中断了。

这个机制允许线程在执行长时间运行的任务时,能够定期检查是否有中断请求,并且能够及时响应这些请求。在这段代码中,如果 futureTask 的执行线程在 sleep 期间被中断,它会抛出 InterruptedException,从而可以在 FutureTaskCallable 中捕获这个异常,并根据需要进行处理,比如清理资源或者提前结束任务。

在实际应用中,如果你的线程执行了一个长时间的任务,你应该定期检查中断状态,并在适当的时候响应中断,以确保你的线程能够及时优雅地停止执行。这通常是通过在循环中检查 Thread.interrupted() 或者在阻塞方法中捕获 InterruptedException 来实现的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/458737.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

navigator.mediaDevices.getUserMedia获取本地音频/麦克权限并提示用户

navigator.mediaDevices.getUserMedia获取本地音频/麦克权限并提示用户 效果获取权限NotFoundErrorNotAllowedError 代码 效果 获取权限 NotFoundError NotAllowedError 代码 // 调用 captureLocalMedia()// 方法 function captureLocalMedia() {console.warn(Requesting lo…

jmeter二次开发函数-生成身份证号

代码参考这个 java 随机生成身份证代码 Java的身份证号码工具类 pom文件添加 <dependency><groupId>org.apache.jmeter</groupId><artifactId>ApacheJMeter_core</artifactId><version>5.4.1</version></dependency><d…

盒子模型...

一&#xff0c;盒子模型 1.1网页布局的本质 1先准备好相关的网页元素&#xff0c;网页元素基本都是盒子BOX。 2利用CSS设置好盒子样式&#xff0c;然后摆放到相应位置。 3往盒子里面装内容。 1.2盒子模型 CSS盒子模型本质是一个盒子&#xff0c;封装周围的HTML元素&#xff…

电路设计(14)——奥运纪念日显示装置的proteus仿真

1.设计要求 北京奥运于2008年8月8日开幕&#xff0c;假设倒计时还剩69天&#xff0c;请你&#xff0c;制作一个电子作品&#xff0c;用以显示上述意思 采用三个数码管&#xff0c;其中一个数码管反复显示2008 8.8&#xff1b;该数码管下方并排放置另两个数码管&#xff0c;这二…

大数据调用链监控平台技术原理

一、AOP技术总结 二、监控逻辑动态织入原理 三、JVM动态织入流程 四、调用链监控平台技术简要总结 &#xff08;一&#xff09;、单服务的无感知自动日志埋点 jvm层面的字节码织入埋点&#xff0c;javaagent方式启动。 &#xff08;二&#xff09;、多服务调用链串联 trace…

hbuiderX打包为apk后无法停止录音的解决方案

同一个APP在hbuilder和hbuilderX打包&#xff0c;出现没有麦克风权限 - DCloud问答 第一步&#xff1a; 在manifest.json的“模块权限配置”中勾选以下权限&#xff1a; <uses-permission android:name"android.permission.MODIFY_AUDIO_SETTINGS" /> <use…

oracle 启动命令以及ORA-01033问题处理、删除归档日志

1 启动数据库:startup 2 关闭数据库&#xff1a;Shutdown immediate 3 查看监听状态&#xff1a;lsnrctl status 4 启动监听&#xff1a;lsnrctl start 5 停止监听&#xff1a;lsnrctl stop 常见问题 1、在服务器重启后会出现&#xff0c;Oracle ORA-01033: ORAC…

找不到concrt140.dll无法继续执行程序的多种解决方法

concrt140.dll文件的丢失可能会对Windows操作系统产生一系列显著的影响。作为系统运行过程中不可或缺的一部分&#xff0c;concrt140.dll是Microsoft Visual C Redistributable Package中包含的重要动态链接库文件&#xff0c;它为应用程序提供了关键的并发运行时支持。一旦该文…

SPSS绘图:直方图的绘制

直方图&#xff08;Histogram&#xff09;又称质量分布图&#xff0c;是一种以组距为底边、以频率为高度的一系列连接起来的直方型矩形图&#xff0c;由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型&#xff0c;纵轴表示分布情况。通过绘制直方…

VSCode如何让先前打开的文件不被自动关闭,一直保持在标签栏里(关闭预览模式)

第一次接触VSCode-Huawei IDE编辑器&#xff0c;每次打开一个新的代码文件&#xff0c;旧的代码文件都会被自动关闭&#xff08;现在才知道是因为文件默认是以预览模式打开展示的&#xff09;。 那么如何才能让先前打开的文件一直保持在标签栏里呢&#xff1f; 我们需要去设置…

树莓派4b连接WQ9201外置无线网卡命令行配置详解

树莓派4B连接WQ9201无线网卡 接线方式 蓝色的线来连接树莓派和WQ9201demo板&#xff0c;USB接树莓派的USB接口&#xff0c;microUSB一端接demo板靠近天线部分的microUSB口。 驱动和固件准备 驱动直接放在树莓派系统的任意目录&#xff0c;目前配置则是将驱动放在树莓派的主目…

CV | SAM在医学影像上的模型调研【20240207更新版】

本文主要是SAM&#xff08;Segment Anything&#xff09;在医学影像上的数据集&#xff0c;模型及评估方法调研【持续更新】~ 1.开源数据集 可参考这篇【数据集 | 基于计算机视觉的医学影像处理数据集_CSDN博客】 2.算法模型 2023.04_SAM 论文&#xff1a;2018.08.05v_Segm…