关于Java中多线程造成的变量共享问题

起因

在自己写的一段代码中,使用到了Redis。代码的逻辑是这样子的,先取出数据,然后判断,再然后将该数据进行自减。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
public boolean isOK(String invitationCode, boolean isSub) {
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
Object count = vo.get(key + invitationCode);
if (count != null && Integer.parseInt(count.toString()) >= 1) {
if (isSub) {
vo.increment(key + invitationCode, -1);
}
return true;
} else {
return false;
}
}

分析

在提交代码的时候,总监复查代码时,提出这段代码可能在并发的时候出现问题:比如有两条线程,都进入到了if(sub){xxx}这段代码,这个时候,就造成了重复多次自减的问题。比如,如果该value是5,那应该减到0就不会再减了,但是这段代码在高并发情况下,可能会出现减到-1的情况。这虽然对于现有的业务影响不大,但是,如果是对于其他的一些比较敏感并且需要精确的数据时,就需要特别注意了。

关键是之前一直没有怎么意识到这段代码可能会造成的问题。之前一直认为,对于局部变量是不会出现多线程问题的,这倒是没有错,但关键是如果是从其他地方传过来而且在多处地方允许被使用的情况下,就需要注意多线程问题。