@RestController
@RequestMapping("/laker")
public class HelloWordController {
private int num = 1;
@GetMapping
@ApiOperation(value = "根据id查询")
public int get() {
int i = num++;
System.out.println(i+Thread.currentThread().getName());
System.out.println(this);
return i;
}
}
Controller是单例。
System.out.println(this)输出的结果相同为同一个实例。会存在线程安全问题。
解决线程安全问题有以下几种方法:
1. 不要用全局成员变量num,可以替换为线程安全的AtomicInteger。
2. 把单例变成多例,使用@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)注解在HelloWordController 类上,多线程调用后结果如下:
3. 使用threadlocal
条件:
线程数:10,循环次数10
预期结果:
实际结果
...
96 http-nio-8080-exec-2
HelloWordController@42e4e589
97 http-nio-8080-exec-4
HelloWordController@42e4e589
98 http-nio-8080-exec-3
HelloWordController@42e4e589
最后为98不是预期的100,典型的线程安全问题,数丢失了。
多线程调用,每次bean的Id都为42e4e589,故为单例。