今天看下别的模块,虽然不是我写的代码,但是我还是看一下,以便全面了解。
如果认为写的不对的地方,我会根据git的提交记录找到对应的人提出自己的
建议。今天,我就看到一个spring关于共享变量的问题。在我们组
中,有个人特别喜欢用共享变量,其实这种用法是不对的。我们知道,spring管理
bean的方式是单例的,对象是存在堆内存中的。废话不多说,直接上代码!
比如说,service层某个实现类有个方法1
2
3
4
5
6
7
8
9
10
11boolean fullLoad = true;
public void testFullload() throws InterruptedException {
System.out.println(Thread.currentThread().getName()+": change="+fullLoad);
fullLoad = !fullLoad;
if(fullLoad){
Thread.sleep(2000);
}else{
Thread.sleep(5000);
}
System.out.println(Thread.currentThread().getName()+": get="+fullLoad);
}
然后在controller层中调这个方法1
2
3
4
5@RequestMapping(value = { "/ping" }, method = RequestMethod.GET)
public ResponseEntity<String> ping() throws InterruptedException {
xxxService.testFullload();
return new ResponseEntity<>("Success", HttpStatus.OK);
}
请求几次后得到的结果1
2
3
4
5
6
7
8http-nio-9103-exec-8: change=true
http-nio-9103-exec-8: get=false
http-nio-9103-exec-1: change=false
http-nio-9103-exec-1: get=true
http-nio-9103-exec-5: change=true
http-nio-9103-exec-5: get=false
http-nio-9103-exec-2: change=false
http-nio-9103-exec-2: get=true
总结:这说明一个多线程的问题,spring 管理bean的方式
是单例的,对象不是放在线程内部独立的内存中的,而是
堆中共享的。使用共享变量特别需要注意,建议作为内部变量
放在方法中传递,而不是作为共享变量的形式传递,因为共享
变量在spring中会把值存储在堆内存中。