如果一个被@Service注解的类的异步方法被一个被注解为@RestController的类调用,我们的服务类的全局变量会在线程间共享吗?
我问这个是因为我知道每个线程都会得到它正在执行的类的本地副本,如果单例类中的共享全局变量不是易变的,它是否仍会共享值或导致脏读或写。
需要注意的是,这两个变量是基元,所以我假设它们将存储在堆栈上而不是堆上。
由于每个线程都将获得类的副本,因为变量是原始变量,所以不会每个线程都在堆栈而不是堆上进行本地更新吗?
@RestController
@RequestMapping(value = "test/v1.0/myputcall")
public class MyController {
@Autowired
MyServiceImpl myServiceImpl;
@PutMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> activate(@RequestBody UserDTO user) {
//Controller calls the async activate method in singleton service class.
myServiceImpl.activate(user.userType, user.userID);
}
}
@Service
public class SwitchServiceImpl{
private int retryCount = 0;
private boolean updateRequired = false;
@Async
public void activate(String userType, String userId){
if(userType=="prod"){
updateRequired=true;
}
if(updateRequired){
tryUpdateWithRetry();
}
private tryUpdateWithRetry(){
for(;count<3;retryCount++){
//call some other app
int status = UpdateUser.update(userId);
if(status==0){
return;
}
}
log.info("update attempted thrice, non zero return status.");
}
}
}
最佳答案
服务将在线程之间共享,它的成员变量也是如此。如果使用 volatile 关键字,这将强制线程从/向主内存而不是缓存读取/写入值 details here .但是,如果多个线程更新该值,这并不能防止脏读/写。
如果值不应该在线程之间共享,你可以使用 ThreadLocal .每个线程都会有一个独立的值副本。如果可能,您还应该考虑在方法内部使用局部变量。
如果需要安全地访问线程间的值,可以使用Atomic variables或使用 synchronized 关键字或锁 details .
关于java - 以异步方式访问时,单例中的类级别变量是否会导致脏读?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64016561/