Java封装同步锁(翻车后续)
最后更新于
这有帮助吗?
最后更新于
这有帮助吗?
封装同步锁
大家好上一期视频翻车了
嗯很多细心的小伙伴发现
其实在1,000并发的时候
就已经出问题了
那为什么呢
为什么100并发没问题
1,000就有问题呢
其实啊原因在于这个springboot
默认的
tomcat最大线程是200个线程
也就是说只要超过200个并发
tomcat会先放200个请求进来
然后每执行完一个请求
tomcat会再放进来一个请求
那这个我们可以验证一下哈
我们在这加一个输出
好
然后我这不用1,000个我们就用205个
大家看
开始结束
每次(结束)都会(进来一个)新请求 大家看
直到第五个后边就没有了
那这样会有什么问题呢
我们来看一下这个方法里
起初他们开的会先放进来200个请求
比如说这200个请求是一起进来的
然后呢他们会被卡在这个地方
我用3个点来代替199个请求
其中有一个请求抢到了锁,先执行进来
然后呢
有199个请求会被卡在这个地方
然后当这一个进来的请求执行到这
他会把这个锁(的引用)从缓存中删掉
再往下执行直到这个请求结束
tomcat会放一个新请求进来
假设这个绿色代表新请求
然后新请求会拿着 key
去缓存里面去找锁
很显然这缓存里面已经没有锁了
所以呢他又创建了一个新的锁
然后新请求在执行到这一步的时候
相当于他的这把锁
跟前面的199个线程 不是一把锁
所以呢他们会并行执行
那怎么解决这个问题呢
设想一下
假如我们不把这个锁从缓存里删掉
再进来新
请求的时候他就会拿到原来那把锁
然后呢他就会在这个后面继续等待
也就是说
加入到了原来那199个行列里面
但是这个缓存就会越来越大
所以我们还是要有一个机制
来删除这个锁
那怎么写呢我们可以这样
我们把这个 Object
换成 ReentrantLock
换成这个
然后呢在这new一个ReentrantLock
这个也是
同时呢我们这就不用这种方法来锁了
还把这个删掉吧
然后调用这把锁的 lock 方法
然后呢
在下面finally里要用他的 unlock
这个remove我们就要判断一下了
有了这个锁呢
我们就可以判断他的等待数量了
等等于0.1幅
如果他等等于0的时候
我们就可以把它remove掉了
相当于没有线程在等待这把锁
我们就把它移除掉好
我们再来试一下哈
把这个先删掉
然后呢我们用1,000个并发
大家看!这个就没有问题了
再见