锁-(分布式锁)

锁是什么

        锁在开发中是避免不了需要接触的,在java中的锁主要是用于保障在多线程并发的情况下数据的一致性

锁可以理解为当多个人去上一个厕所,当里面有人的时候先抢到厕所的时候,里面的人将门栓锁上,后面的人想上厕所时候发现里面有人,就会在外面等候厕所里面的人出来,就如线程,当一个线程获得了锁去访问公共资源,这时其他的线程去访问这个公共资源的时候,就会发现线程已经上了锁,所以就会进入等待

不加锁会发生什么情况

当并发的线程不加锁的时候会发生什么事情,例如常见的超卖问题

库存类:有50的商品库存

@Data
public class Stock {

    //商品库存数
    private Integer stock=50;
}

构建一个方法

@Service
public class StockService {

    private Stock stock=new Stock();

    //买东西方法
    public void payStock(){
        if (stock.getStock()>0){
            //买东西库存-1
            stock.setStock(stock.getStock()-1);
            System.out.println("剩余库存数"+stock.getStock());
        }else {
            System.out.println("本期抢购已售完");
        }
    }

}

调用方法

@GetMapping("stock/pay")
    public String getPayStock(){
        stockService.payStock();
        return "hello!";
    }

当我们使用JMeter模拟并发情况的时候发现,商品出现超抢购的数量比库存的数量多

 这时,我们只要在方法加锁(synchronized)问题就会解决

 //买东西方法
    public synchronized void payStock(){
        if (stock.getStock()>0){
            stock.setStock(stock.getStock()-1);
            System.out.println("剩余库存数"+stock.getStock());
        }else {
            System.out.println("本期抢购已售完");
        }
    }

 

 

但是这不是最好的解决方案,要不然为什么会有那么多锁,在不同的业务使用不同的锁,具体还是需要根据业务需求来选择

什么时候锁会失效

        多例模式:在单例模式的情况下锁不会失效,但是在多例的情况下锁会失效可以在方法类上加上@Scope注解自行尝试:prototype:多例模式

@Scope(value = "prototype",proxyMode = ScopedProxyMode.TARGET_CLASS )

        事务:两个线程同时开启事务,a线程先获取到锁,a线程执行完减商品后释放锁的同时b线程立马获取到了锁,且查询到了商品的数量,a线程还未提交,这时两个线程获取到的数量是一样的,在数据库中set相同的值。可在方法类上添加@Transactional开启事务自行尝试。

        集群部署:情况就如单例模式差不多,当项目部署在多个服务器的时候,并发情况下每个服务器会访问一个共享资源,这时,服务器里都有一个实例,这时加锁就会失效

解决:使用更新sql语句完成判断以及更新数据(写操作本身会加锁),这样会解决上面锁失效的问题,但是也会有新的问题:

        1.锁的范围问题

        2.同一个商品有多条库存记录,这样一个sql语句难以解决这个问题

        3.无法记录库存的变化状态

        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值