You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java调用interrupt()后RAM监控线程仍持续打印内存占用的问题

问题原因

你现在的问题核心是调用错了interrupt方法:

  • 主类里的thread_RAM.interrupt()调用的是Java原生Thread类的interrupt(),它只会给线程打上中断标记,并不会触发你在RAMMonitor里自定义的interrupt()方法(也就是那个把isRunning设为false的方法)。
  • 同时,RAMMonitor的run()方法里,捕获InterruptedException后只是重新设置了中断标记,但没修改isRunning的值,所以while(isRunning)的循环条件一直为true,线程会无限跑下去。
修复方案

有两种靠谱的修复方式,选一种就行:

方案1:正确触发自定义的中断逻辑

修改主类的interruptMonitoring()方法,直接调用RAMMonitor实例的interrupt()方法,同时保留Thread的interrupt来唤醒sleep中的线程:

public void interruptMonitoring() {  
    // 先调用自定义的interrupt,把isRunning设为false
    monitor_RAM.interrupt();
    // 再调用Thread的interrupt,唤醒sleep中的线程,让它立刻检查循环条件
    thread_RAM.interrupt();
    
    try {  
        thread_RAM.join();
    } catch (InterruptedException e) {
        // 打印异常信息方便调试
        e.printStackTrace();
    }
}

这样一来,sleep的线程会被唤醒,同时循环条件isRunning已经是false,循环会直接终止。

方案2:结合中断标记判断循环条件

如果不想依赖自定义的isRunning变量,也可以直接用线程的中断状态来控制循环,更符合Java线程中断的设计:
修改RAMMonitor的代码:

public class RAMMonitor implements Runnable {

    @Override
    public void run() {
        // 循环条件改为检查当前线程的中断状态
        while (!Thread.currentThread().isInterrupted()) {
            long usedMemory = getUsedMemory();
            long totalMemory = getTotalMemory();
            double memoryUsage = (double) usedMemory / totalMemory * 100;

            System.out.println("RAM Usage -----> " + (int) memoryUsage + "%");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // 捕获异常后中断标记会被清除,重新设置标记
                Thread.currentThread().interrupt();
            }
        }
    }

    // 以下方法保持不变
    private long getUsedMemory() {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }
    private long getTotalMemory() {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory();
    }
}

这种情况下,主类的interruptMonitoring()方法不需要修改,调用thread_RAM.interrupt()后,线程要么在sleep时被唤醒并重新设置中断标记,要么在下次循环时检测到中断状态,从而终止循环。

额外建议
  • 不要空捕获InterruptedException,至少打印异常栈信息,方便排查问题。
  • 用volatile修饰isRunning是正确的,保证了多线程下的变量可见性,这点你做的没问题。

内容的提问来源于stack exchange,提问作者Vertos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 17:37:08