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

Java线程运行时变量值始终保持不变的原因排查求助

问题分析与解决方案

嘿,我来帮你排查这个线程问题~你的代码里有几个关键问题导致time变量始终不变,咱们一步步来解决:

核心问题:线程根本没执行timer()方法

当你调用timerobj.start()时,Java的Thread类会自动执行**run()方法**,但你的Intro_using_Thread类并没有重写run()方法,默认的run()什么都不做——你的timer()方法完全没被调用过,time变量当然不会有变化啦!

修复步骤

1. 重写run()方法,关联timer逻辑

在Intro_using_Thread类里添加重写的run()方法,让线程启动后执行timer():

@Override
public void run() {
    timer();
}

2. 修正timer()的循环逻辑

你当前的循环写法会导致time被错误地多次递减:

// 原错误逻辑:i从初始time开始,每次循环既i--又time--,会让time减得比预期多很多
for (int i = time; i >= 0; i--) {
    time--;
    // ... sleep
}

改成更直观的while循环,确保time从初始值逐步减到0:

public void timer() {
    while (time > 0) {
        time--;
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3. 解决线程内存可见性问题

主线程在while (timerobj.time!=0)里读取time变量时,可能因为线程缓存看不到子线程修改后的最新值,所以需要把time声明为volatile,保证变量的修改对所有线程可见:

volatile int time;

修改后的完整代码

线程类(Intro_using_Thread.java)

package Threading;

public class Intro_using_Thread extends Thread {
    volatile int time;

    public Intro_using_Thread(int time) {
        this.time = time;
    }

    @Override
    public void run() {
        timer();
    }

    public void timer() {
        while (time > 0) {
            time--;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

驱动类(Intro_using_thread_run.java)

package Threading;

import java.util.Scanner;

public class Intro_using_thread_run {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 建议先用小数值测试,比如10,方便看到变化
        Intro_using_Thread timerobj = new Intro_using_Thread(10);
        timerobj.start();
        
        // 原代码的in.nextInt()会阻塞主线程,改为自动每秒打印time变化
        while (timerobj.time != 0) {
            System.out.println("The time is = " + timerobj.time);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        in.close();
        System.out.println("Time's up!");
    }
}

额外说明

如果你坚持保留输入触发打印的逻辑,那原驱动类的choice = in.nextInt()也可以用,但要注意输入会阻塞主线程,只有当你输入内容时才会打印当前time值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 07:02:47