作者热门文章
- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我想知道一个类的每个实例是否都有自己的该类方法的副本?
可以说,我有以下类(class) MyClass
:
public MyClass {
private String s1;
private String s2;
private String method1(String s1){
...
}
private String method2(String s2){
...
}
}
因此,如果两个不同的用户创建 MyClass
的实例,例如:
MyClass instanceOfUser1 = new MyClass();
MyClass instanceOfUser2 = new MyClass();
是否知道每个用户在他的线程中都有一份 MyClass
方法的副本?如果是,那么实例变量就是线程安全的,只要只有实例方法操作它们,对吧?
我问这个问题是因为我经常读到实例变量不是线程安全的。当每个用户通过调用 new
运算符获取实例时,我看不出为什么会这样?
最佳答案
每个对象都有自己的类实例变量的副本 - 它是在类的所有实例之间共享的 static
变量。实例变量不一定是线程安全的原因是它们可能被多个线程调用不同步的实例方法同时修改。
class Example {
private int instanceVariable = 0;
public void increment() {
instanceVariable++;
}
}
现在,如果两个不同的线程同时调用 increment
,那么您就会遇到数据竞争 - instanceVariable
可能会在两个方法结束时递增 1 或 2返回。您可以通过将 synchronized
关键字添加到 increment
或使用 AtomicInteger
而不是 int
来消除这种数据竞争等,但重点是,仅仅因为每个对象都有自己的类实例变量的副本,并不一定意味着变量是以线程安全的方式访问的——这取决于类的方法。 (异常(exception)是 final
不可变变量,它不能以线程不安全的方式访问,没有像序列化 hack 这样愚蠢的东西。)
关于java - 实例方法和实例变量的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17886150/
我是一名优秀的程序员,十分优秀!