线程并发的情景
程序员文章站
2022-03-25 21:28:08
...
最近写了一个高并发的代码
public String getTicketForRedis(){
Long ticket = redisTemplate.opsForValue().decrement("ticket");
ticket = ticket--;
if(ticket>=0){
//减票数
ticketService.updateTicketNum();
System.out.println("票号为:"+ ticket);
return "票号为:"+ ticket;
}else{
return "光了";
}
}
一直以为出现线程不安全的地方是 ticket = ticket–;if(ticket>=0) 就是这个ticket可能是同一个数,为什么是同一个数那 因为当线程切换时,ticket = tocket-- 不是原子性的。咋一看,是有道理 其实不然 这个方法内的操作,根据jvm内存模型,方法内的变量在方法栈中 每个线程都有一个方法栈,切线程安全,互不影响。所以 方法内的所有操作,都是线程安全的。但这里在高并发下确实会出现票的超卖。问题在于获取ticket时 由于mysql的原因,每个线程很可能取到相同的数,所以减票数会出现超过100张票数。
总结:
引起 线程问题的原因: 1 成员变量 2 数据库引入方法中的局部变量
下一篇: nginx重定向路径