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

Android Java中双线程修改score变量后值未更新问题求助

线程间变量可见性问题排查与解决

问题场景

定义了int类型变量score,实现两个线程Hilo1和Hilo2:

  • Hilo1每30秒执行一次,在UI线程弹出Toast显示当前score值
  • 当某次评估结果为真时启动Hilo2,Hilo2延迟movementTimeThread时长后,在UI线程调用tranquilo()方法,返回true则给score加1
    已确认Hilo2正常执行且tranquilo()返回true,但Hilo1下次显示的score仍为0。

相关代码

Hilo1 代码

class Hilo1 extends Thread {
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(30000);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(Course.this, "SCORE="+score, Toast.LENGTH_SHORT).show();
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Hilo2 代码

class Hilo2 extends Thread {
    @Override
    public void run() {
            try {
                Thread.sleep(movementTimeThread);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if(tranquilo(currentHeartRate,higherHeartRate,lowerHeartRate,changeInAcceleration)){
                            score=score+1;
                            /*textViewPuntuacion.setText("Puntuacion= ");*/
                        }else {
                            vecesNoCalmado = vecesNoCalmado + 1;
                        }
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }
}

问题根源

普通int类型的score没有线程可见性保证:
Java中每个线程都有自己的工作内存,会缓存共享变量的副本。Hilo2在UI线程修改score后,这个修改只会更新UI线程的工作内存,Hilo1的工作内存里的score副本不会自动同步主内存的新值,导致Hilo1读取的始终是初始的0。

解决方案

方案1:给score添加volatile修饰符

修改变量定义,强制所有线程直接读写主内存中的score值,保证修改后其他线程能立即看到:

volatile int score = 0;

方案2:使用原子类AtomicInteger(更推荐多线程并发场景)

如果后续存在多个线程同时修改score的情况,用AtomicInteger可以避免竞态条件,它的原子操作是线程安全的:

// 初始化
AtomicInteger score = new AtomicInteger(0);

// Hilo2中修改score
score.incrementAndGet();

// Hilo1中读取score
Toast.makeText(Course.this, "SCORE="+score.get(), Toast.LENGTH_SHORT).show();

辅助检查

确认每次评估为真时,Hilo2是通过new Hilo2().start();正确启动的,避免出现线程创建但未启动的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 01:22:02