java 中 ReentrantLock 高并发响应时间控制

发布于 2021-12-02 03:49:22 字数 419 浏览 931 评论 10

有这么一个需求,一个list里面存放的一堆数字的集合,每次请求需要从这个list 中获取所有要的数目,然后更新list,为了保证list 操作安全,和list 里面存放的数据不丢失,引用了Memcached,ReentrantLock

如下:


在一个接口高并发情况下,ReentrantLock 锁效率急剧下降……

求大神高招指点啊

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

少女情怀诗 2021-12-03 18:52:50

先指出你一个问题,unlock()一定要放在finally块中

其次,上面说用CopyOnWriteArrayList等的欠妥,CopyOnWriteArrayList只能保证单个方法内是原子线程安全的,但你描述的业务逻辑明显没办法用CopyOnWriteArrayList中的某一个方法完成,是需要在一个业务逻辑内完全保持锁的

再然后,我估计这段代码的并发效率并不在锁的性能上,而是你本身这个业务逻辑的并发性能就不行。每次业务逻辑上至少调用两次memcached缓存,光这网络通信以及和memcached交互就至少要消耗5ms以上,加上其他的代码逻辑,你这单个业务逻辑估计耗时在8ms以上,还要求完全独占锁,秒并发再高也搞不到哪里

解决方法 1.优化业务逻辑,甚至重构 2对资源进行分片,每次只锁需要资源占用的片段,可以理解下ConcurrentHashMap中的思想

陌上芳菲 2021-12-03 18:52:06

既然是高并发,还使用锁,这必然会效率下降的很厉害,可以考虑从业务逻辑上改造,技术人员不能光一味的研究某种技术吧,我觉得需要变通,自己去设计符合自己业务场景的

明媚如初 2021-12-03 18:48:10

可以考虑试试concurrenthashmap的实现方法,我们做一个标志,当标志和获取的大小满足一个关系时,就不加锁处理,当不满足时就采用枷锁处理,反正是添加,不如锁分段的方式。

秋意浓 2021-12-03 18:43:54

程序逻辑方面不好改了,memcached的类型支持太弱,利用redis试试,自己加入细粒度锁

把昨日还给我 2021-12-03 18:33:32

CopyOnWriteArrayList 这个我有考虑,但是真正的数据是存放在memcached 的,每一个线程过来都是从cache 里面取出list,操作完写会cache

别低头,皇冠会掉 2021-12-03 18:19:26

感觉应该推荐你CopyOnWriteArrayList,高并发最好是避免直接锁线程

把回忆走一遍 2021-12-03 16:40:02

如果读取操作比较多的时候,可以用

CopyOnWriteArrayList
坚持沉默 2021-12-03 14:55:03

小白表示看不懂,好高深的样子!为什么不用

Collections.synchronizedList?

等你爱我 2021-12-03 14:06:52

为啥要在java端锁数据,直接用memcached incr 这种有cas原子运算的做一个乐观锁就可以了

伪代码:

while(true){
  String memKeyOL = "xxxxx-OL";

  int seed = memcached.incr(memKeyOL);

  List contents = memcached.get("xxxxx");

  //TODO something with contents


  int nowSeed =  memcached.get(memKeyOL);
   
  if(nowSeed==seed ){
    memcached.put("xxxxx",contents )
    break;
  }

}

悲喜皆因你 2021-12-03 13:29:46

引用来自“kidding”的评论

为啥要在java端锁数据,直接用memcached incr 这种有cas原子运算的做一个乐观锁就可以了

伪代码:

while(true){
  String memKeyOL = "xxxxx-OL";

  int seed = memcached.incr(memKeyOL);

  List contents = memcached.get("xxxxx");

  //TODO something with contents


  int nowSeed =  memcached.get(memKeyOL);
   
  if(nowSeed==seed ){
    memcached.put("xxxxx",contents )
    break;
  }

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文