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

Java多线程调用静态B对象方法后a属性值为何不是1?

class B {
    int a = 0;
    void method1() {
        // code
        a = a + 1;
    }
}

public class A extends Thread {

    static B obj1;

    public void run(){
       obj1.method1();
    }

    public static void main(String args[]){
        obj1 = new B();
        A a1 = new A();
        a1.start();
        A a2 = new A();
        a2.start();      
    }
}
静态引用obj1的工作机制

Java中被static修饰的成员属于类本身,不与类的实例绑定,整个程序运行期间全类共享同一份存储。
代码中A类的static B obj1是A类的静态成员,仅在A类加载时完成一次初始化,不管创建多少个A类的实例(比如代码中的a1、a2两个线程实例),所有实例访问的都是同一个obj1引用。
你在main方法中仅执行了一次obj1 = new B(),所以a1、a2两个线程执行run()方法中的obj1.method1()时,操作的是同一个B类对象,不存在每个线程持有独立B对象的情况。

你认为B类a属性值为1的认知疏漏

主要存在两个层面的错误:

  • 对static修饰符的作用认知偏差:你默认认为不同的A线程实例会持有各自独立的B类对象,按这个逻辑每个线程只会给各自持有的B对象的a属性加1,结果才会是1。但实际上两个线程操作的是同一个B对象的a属性,如果两个线程的method1完全串行执行,a的结果应该是2,而非1。
  • 忽略了多线程环境下的竞态条件:a = a + 1不是原子操作,执行时会被拆分为3个独立步骤:读取a的当前值、计算a+1的结果、将新值写回a。两个线程同时执行这段逻辑时可能出现指令交错:比如线程1读取到a=0,还没来得及将加1后的结果写回,线程2也读取到a=0,两个线程都计算出结果1再依次写回,最终a的结果就会是1。但这种情况是随机出现的,不是必然结果,这段代码运行后a的值可能是1也可能是2,没有固定的预期结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:39:04