一尘不染

实例方法和实例变量的线程安全

java

我想知道一个类的每个实例是否在该类中都有自己的方法副本?

可以说,我有以下课程MyClass

public MyClass {

    private String s1;

    private String s2;

    private String method1(String s1){
    ...
    }

    private String method2(String s2){
    ...
    }
}

因此,如果两个不同的用户创建了MyClasslike这样的实例:

MyClass instanceOfUser1 = new MyClass();
MyClass instanceOfUser2 = new MyClass();

是否知道每个用户在其线程中都有的方法的副本MyClass?如果是,则实例变量是线程安全的,只要只有实例方法对其进行操作,对吗?

我问这个问题是因为我经常读到实例变量不是线程安全的。而且,当每个用户通过调用new运算符获取实例时,我不明白为什么会这样?


阅读 187

收藏
2020-12-03

共1个答案

一尘不染

每个对象都有自己的类实例变量的副本-
在类的static所有实例之间共享的变量。实例变量不一定是线程安全的,原因是它们可能被调用异步实例方法的多个线程同时修改。

class Example {
    private int instanceVariable = 0;

    public void increment() {
        instanceVariable++;
    }
}

现在,如果两个不同的线程同时调用increment,那么您将发生数据争用-
instanceVariable在返回的两个方法结束时,可能会增加1或2。您可以通过将synchronized关键字添加到increment,或使用a
AtomicInteger而不是int等来消除这种数据争用,但要点是,仅仅因为每个对象都获得了自己的类实例变量的副本,并不一定意味着变量可以在线程安全的方式-
这取决于类的方法。(例外是final不可变的变量,它不能以线程不安全的方式进行访问,缺少像序列化黑客这样的愚蠢的东西。)

2020-12-03