欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线程并发的情景

程序员文章站 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 数据库引入方法中的局部变量