【发布时间】:2021-05-12 16:04:10
【问题描述】:
我在尝试理解和修复 Fortify 扫描报告的错误时遇到了一些问题。我有这门课:
public class DaoImpl extends BaseDaoImpl {
private static volatile String sNric;
synchronized private void setInfo(InfoTO pers) {
sNric = pers.getNRIC();
}
synchronized public InfoTO getInfo() {
InfoTO pers = new InfoTO();
sNric = retrieveDetail();
pers.setNRIC(sNric);
}
synchronized private String retrieveDetail() {
// some logic to get info from database
}
}
我的代码最初没有 static volatile 和 synchronized 关键字。 Fortify 在sNric 和sNric = retrieveDetail(); 的变量声明中报告了Race Condition: Singleton Member Field 警告
我去研究发现this solution。但是,我不太确定 volatile 和 synchronized 的概念。上面提出的解决方案会导致一些死锁问题吗?
【问题讨论】:
-
volatile不会把你从种族中拯救出来,不是那个。您需要明确区分可见性和原子性,或两者兼而有之。 -
为什么
sNric是静态的?鉴于它只能通过非静态方法访问,我认为该字段也应该是非静态的。如果有多个DaoImpl实例,则会发生争用情况,因为您的方法在一个实例上同步,而该字段是静态的。 -
@MarkRotteveel 更大的问题是,为什么这个变量存在?唯一的读取紧跟在写入之前,因此
sNric = retrieveDetail(); pers.setNRIC(sNric);可以替换为pers.setNRIC(retrieveDetail());,这表明setInfo对sNric的写入根本没有效果,没有人会读取该值。跨度> -
@MarkRotteveel 一个影响何时访问哪个变量的代码简化对于线程安全问题来说是不可行的。由于数据访问是线程安全(防止数据竞争)的全部意义所在……
-
@MarkRotteveel 我们不知道这种过度简化是否真的发生过。 OP 的真实代码也可能像这里显示的那样毫无意义。这不是一个密切的原因。
标签: java multithreading synchronized volatile