如何解决 Fortify Race Condition: Singleton Member Field 问题
How to fix Fortify Race Condition: Singleton Member Field issue
我遇到了问题。
我们在我的项目中使用 Spring MVC 框架,但 Spring MVC 默认控制器是单例模型。
我通过会话更改控制器使用 @Scope("session") 以避免竞争条件问题(每个人都有自己的控制器)。
@Controller
@Scope("session")
public class AP0Controller extends BaseController {
@Autowired
GnRecService gnRecService;
Integer seq = null;//Global variable
@RequestMapping(value = "/agn/AP1W01A_004", method=RequestMethod.GET)
public ModelAndView welcomeGrid(@RequestParam("payType")String payType){
seq = gnRecService.findTheLastPK(payType);
ModelAndView view = new ModelAndView(".agn.AP1W01A_004");
return view;
}
public ModelAndView showPk() {
seq +=2;
ModelAndView view = new ModelAndView(".agn.AP1W01A_004");
view.addObject("seq",seq)
return view;
}
}
经 HP Fortify 扫描后,报告表明这将导致竞争条件。
我怎样才能解决它并解决这个问题?
seq +=2;//Race Condition: Singleton Member Field
尝试重新设计您的控制器,不要将状态放入其中。
或者你可以考虑使用 AtomicInteger
AtomicInteger seq = new AtomicInteger();//Global variable
@RequestMapping(value = "/agn/AP1W01A_004", method=RequestMethod.GET)
public ModelAndView welcomeGrid(@RequestParam("payType")String payType){
seq.set(gnRecService.findTheLastPK(payType));
ModelAndView view = new ModelAndView(".agn.AP1W01A_004");
return view;
}
public ModelAndView showPk() {
final int localSeq = seq.addAndGet(2);
ModelAndView view = new ModelAndView(".agn.AP1W01A_004");
view.addObject("seq",localSeq)
return view;
}
当我们在 class 中声明一个实例变量并在同一 class.
中的任何方法中使用该实例变量时,就会发生竞争条件
public class Test {
private boolean isRaceCondition;
private String myRaceCondition;
public void testMyMethod(){
If(isRaceCondition){
myRaceCondition= "Yes It is";
}
else{
myRaceCondition= "No It is not";
}
}}
以上代码在单线程环境中 运行 正确,但在多线程环境中,可能有多个线程在处理同一段代码,并可能导致数据完整性问题。
例如,线程 T1 设置了 isRaceCondition= true 的值,但在 T1 可以执行方法 testMyMethod() 之前,另一个线程 T2 重置了 isRaceCondition= false 的值,所以现在当 T1 尝试执行 testMyMethod() 时,它将看到 isRaceCondition 为 false,它将设置 myRaceCondition= “No It is not”;
要解决这个问题,最简单的方法是
如果我们可以将初始值设置为变量并且本质上它们是常量。
private static final boolean isRaceCondition=True;
private static final String myRaceCondition="Yes It is" ;
否则如果我们不能设置初始值,我们使用volatile。这将确保变量的值总是在使用之前从内存中获取
private static volatile boolean isRaceCondition;
private static volatile String myRaceCondition;
对于字符串和其他对象竞争条件,我们应该使用 AtomicReference 竞争 condition.for 示例私有 AtomicReference 名称并生成 setter 和 getter,同样对于用户定义的对象 AtomicReference person 并为此生成 setter 和 getter,您的竞争条件是解决了。
我遇到了问题。 我们在我的项目中使用 Spring MVC 框架,但 Spring MVC 默认控制器是单例模型。 我通过会话更改控制器使用 @Scope("session") 以避免竞争条件问题(每个人都有自己的控制器)。
@Controller
@Scope("session")
public class AP0Controller extends BaseController {
@Autowired
GnRecService gnRecService;
Integer seq = null;//Global variable
@RequestMapping(value = "/agn/AP1W01A_004", method=RequestMethod.GET)
public ModelAndView welcomeGrid(@RequestParam("payType")String payType){
seq = gnRecService.findTheLastPK(payType);
ModelAndView view = new ModelAndView(".agn.AP1W01A_004");
return view;
}
public ModelAndView showPk() {
seq +=2;
ModelAndView view = new ModelAndView(".agn.AP1W01A_004");
view.addObject("seq",seq)
return view;
}
}
经 HP Fortify 扫描后,报告表明这将导致竞争条件。 我怎样才能解决它并解决这个问题?
seq +=2;//Race Condition: Singleton Member Field
尝试重新设计您的控制器,不要将状态放入其中。 或者你可以考虑使用 AtomicInteger
AtomicInteger seq = new AtomicInteger();//Global variable
@RequestMapping(value = "/agn/AP1W01A_004", method=RequestMethod.GET)
public ModelAndView welcomeGrid(@RequestParam("payType")String payType){
seq.set(gnRecService.findTheLastPK(payType));
ModelAndView view = new ModelAndView(".agn.AP1W01A_004");
return view;
}
public ModelAndView showPk() {
final int localSeq = seq.addAndGet(2);
ModelAndView view = new ModelAndView(".agn.AP1W01A_004");
view.addObject("seq",localSeq)
return view;
}
当我们在 class 中声明一个实例变量并在同一 class.
中的任何方法中使用该实例变量时,就会发生竞争条件 public class Test {
private boolean isRaceCondition;
private String myRaceCondition;
public void testMyMethod(){
If(isRaceCondition){
myRaceCondition= "Yes It is";
}
else{
myRaceCondition= "No It is not";
}
}}
以上代码在单线程环境中 运行 正确,但在多线程环境中,可能有多个线程在处理同一段代码,并可能导致数据完整性问题。
例如,线程 T1 设置了 isRaceCondition= true 的值,但在 T1 可以执行方法 testMyMethod() 之前,另一个线程 T2 重置了 isRaceCondition= false 的值,所以现在当 T1 尝试执行 testMyMethod() 时,它将看到 isRaceCondition 为 false,它将设置 myRaceCondition= “No It is not”;
要解决这个问题,最简单的方法是 如果我们可以将初始值设置为变量并且本质上它们是常量。
private static final boolean isRaceCondition=True;
private static final String myRaceCondition="Yes It is" ;
否则如果我们不能设置初始值,我们使用volatile。这将确保变量的值总是在使用之前从内存中获取
private static volatile boolean isRaceCondition;
private static volatile String myRaceCondition;
对于字符串和其他对象竞争条件,我们应该使用 AtomicReference 竞争 condition.for 示例私有 AtomicReference 名称并生成 setter 和 getter,同样对于用户定义的对象 AtomicReference person 并为此生成 setter 和 getter,您的竞争条件是解决了。