我有一个java类如下
class User {
String name;
String phone;
public String getName() {
return name;
}
public String getPhone() {
return phone;
}
}
该类的使用方式是,为每个线程创建 1 个该 User 类的对象。现在,由于每个线程都有一个对象副本,我可以将此类称为线程安全的吗?
我需要同步这些方法吗?
对于一个线程安全的类,无论有多少线程访问它,它的不变量和后置条件都应该成立。
对于此类,虽然没有写入方法,但仍然需要同步读取。这是因为编译器可以缓存状态变量(在本例中name
and phone
)对于每个线程(记住每个线程都有自己的一组寄存器)。因此,如果一个线程更新任何状态变量的值,另一个线程可能看不到它,并且可能会读取过时的值。
避免这种情况的一个非常简单的方法是使状态变量volatile
。但它是一个弱同步原语,并且不提供像synchronized
does.
这是使此类线程安全的正确方法:
class User {
GuardedBy("this")String name;
GuardedBy("this")String phone;
public synchronized String getName() {
return name;
}
public synchronized String getPhone() {
return phone;
}
}
注意:每个状态变量可以使用不同的锁,具体取决于您的要求。我假设这两个变量以某种方式一起参与一个不变量。
弱同步:
class User {
volatile String name;
volatile String phone;
public String getName() {
return name;
}
public String getPhone() {
return phone;
}
}
For synchronized
方法,每次线程调用它们时,它都会刷新其缓存并从内存中读取最新值,并且每次存在时synchronized
方法,它将变量的最新值放入内存中。
过时的读取可能会更加危险64b
double
and long
,因为在 Java 中写入和读取这些数据类型不是原子的,可以在 2 中完成32b
运营。这可能会导致一些非常糟糕的后果。
编辑:刚刚看到每个线程都有自己的对象副本。在这种情况下,不需要同步。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)