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

Java并发问题:使用synchronized关键字仍得到错误结果

问题原因与修复方案

核心问题1:主线程未等待子线程执行完毕

你在主线程中启动tA和tB两个线程后,立刻调用getRawBalance()打印余额,但此时这两个子线程可能还没开始执行、只完成了一个,或者刚好都执行完。主线程和子线程的执行顺序由操作系统调度决定,所以每次运行的结果都不确定。

核心问题2:getRawBalance()存在可见性问题

balance是非volatile变量,且getRawBalance()没有同步机制。即使子线程已经完成存款操作,主线程也可能无法读取到balance的最新值,因为线程的工作内存和主内存之间的更新没有同步保证。

额外bug:rawWithDraw()的判断逻辑错误

rawWithDraw()里的判断条件写的是if (balance >= balance),这永远为true,不管余额是否足够,都会执行扣款,这是明显的逻辑错误,应该改成if (balance >= amount)。


修复后的代码示例

修改后的Main类(等待子线程执行+用同步方法获取余额)

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Account account1 = new Account(0);
        Thread tA = new Thread(() -> account1.safeDeposit(70));
        Thread tB = new Thread(() -> account1.safeDeposit(50));
        tA.setName("thread-A");
        tB.setName("thread-B");
        tA.start();
        tB.start();
        
        // 等待两个子线程执行完成
        tA.join();
        tB.join();
        
        // 使用同步的getSafeBalance()保证可见性
        System.out.println("The balance is : " + account1.getSafeBalance());
    }
}

修正后的rawWithDraw()方法

public boolean rawWithDraw(int amount) {
    if (balance >= amount) { // 修正判断条件
        balance = balance - amount;
        return true;
    }
    return false;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 16:56:03