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

Jerry-hu 发布于 2016/05/23 22:51
阅读 746
收藏 1

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

如下:


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

求大神高招指点啊

加载中
0
k
kidding

引用来自“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;
  }

}



认真得猜了一下楼主的需求

核心就是要做一个资源池,需要了take一个,不需要了就return回来

如其他人所说redis更适合你,memcached没有办法持久化,宕机就会有一致性的问题

还有就是只用数据库做,数据库的一致性和持久性都是memcached比不了的

同时这里memcached要取出大量的数据,网络通信成本相当高


最后,若有zookeeper,这里也比较好做,序列化节点即可,recipe里的例子就是queue的实现了

1
k
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;
  }

}



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

Collections.synchronizedList?

0
Aaron_Sheperd
Aaron_Sheperd
如果读取操作比较多的时候,可以用
CopyOnWriteArrayList
0
Jerry-hu
Jerry-hu
因为我只是一次读取,每次读取完更新会重新写入Memcached的……
0
暴走的蛇
暴走的蛇
感觉应该推荐你CopyOnWriteArrayList,高并发最好是避免直接锁线程
Jerry-hu
Jerry-hu
CopyOnWriteArrayList 这个我有考虑,但是真正的数据是存放在memcached 的,每一个线程过来都是从cache 里面取出list,操作完写会cache
0
小云1983
小云1983
程序逻辑方面不好改了,memcached的类型支持太弱,利用redis试试,自己加入细粒度锁
0
xpbob
xpbob
可以考虑试试concurrenthashmap的实现方法,我们做一个标志,当标志和获取的大小满足一个关系时,就不加锁处理,当不满足时就采用枷锁处理,反正是添加,不如锁分段的方式。
0
Gillian_Male
Gillian_Male
既然是高并发,还使用锁,这必然会效率下降的很厉害,可以考虑从业务逻辑上改造,技术人员不能光一味的研究某种技术吧,我觉得需要变通,自己去设计符合自己业务场景的
0
首席打酱油
首席打酱油

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

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

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

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

返回顶部
顶部