JVM本地锁(一)简单实现

JVM本地锁由ReentrantLock或synchronized实现

模拟场景

假设有个共享库存资源,多线程进行访问,每次访问库存-1.

@Data
public class StockDemo {
    private Integer stock = 5000;
}

再controller -> service 进行访问调度

@Service
public class StockDemoService {
    private StockDemo stockDemo = new StockDemo();
    
    public void deduct(){
        stockDemo.setStock(stockDemo.getStock()-1);
        System.out.println("库存余量:" + stockDemo.getStock());
    }
}

注意:此时的stockDemo是单例模式,所有请求进来访问的是一个stockDemo实例。

@RestController
public class StockDemoController {

    @Autowired
    private StockDemoService stockDemoService;

    @GetMapping("/local/stock/deduct")
    public String deduct(){
        stockDemoService.deduct();
        return "hello stock deduct";
    }
}

端口号设置为10010.

启动完成后,通过页面访问
在这里插入图片描述

访问成功。

Jmeter并发测试

在这里插入图片描述
新建线程组,100个线程,每个线程发50个请求,请求间隔时间1s.

在这里插入图片描述
新建Http request,配置好发送路径
在这里插入图片描述
再配置好报表。

开始测试。
在这里插入图片描述

5000个请求执行完毕,吞吐量1520,没有错误。
那么如果正常来说,库存量此时应该是0。

在这里插入图片描述
查看控制台,发现最后库存并不是0,是604。
于是发生了超卖问题。即明明5000个商品已经卖完了,可是你显示还有库存,别的用户就还可以买。

synchronized

可以用synchronized解决,只要在service方法中加一个synchronized

@Service
public class StockDemoService {
    private StockDemo stockDemo = new StockDemo();

    public synchronized void deduct(){
        stockDemo.setStock(stockDemo.getStock()-1);
        System.out.println("库存余量:" + stockDemo.getStock());
    }
}

重启后成功,再用jmeter测试。
在这里插入图片描述
吞吐量明显升高了,1653。

synchronized的底层实现主要依靠 Lock-Free 的队列,基本思路是 自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量

再看控制台
在这里插入图片描述
库存清空,问题解决。

ReentrantLock

用ReentrantLock实现,修改下service方法

@Service
public class StockDemoService {
    private StockDemo stockDemo = new StockDemo();

    private ReentrantLock lock = new ReentrantLock();

    public void deduct(){
        lock.lock();
        try{
            stockDemo.setStock(stockDemo.getStock()-1);
            System.out.println("库存余量:" + stockDemo.getStock());
        }finally {
            lock.unlock();
        }
    }
}

注意:用的是try finally,为了保证最后肯定会调用lock.unlock()。

重启后再进行Jmeter测试

在这里插入图片描述
吞吐量明显降低,1035。

在这里插入图片描述
问题同样解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

范大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值