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个并发

大家看!这个就没有问题了

再见

最后更新于