为了账号安全,请及时绑定邮箱和手机立即绑定

如何手动撸一个能够满足下列并发的队列?

如何手动撸一个能够满足下列并发的队列?

四季花海 2019-05-24 15:59:42
在做puv统计时碰到的一个问题,用户请求过来会记录为一个pv,记录到redis中,但由于pv量太大会给redis造成过大压力,所以做个缓存,当pv满10条了发一次。用了一个队列ArrayList实现,但队列的插入、删除在并发条件下不可行,所以在方法上加了synchronized:staticArrayListpvList=newArrayList();publicsynchronizedvoidcountPv(...){//........生成一个PV对象pvList.add(PV)if(pvList.size()>10){//前10个加到redisaddRedis(pvList.subList(0,10))}//删除10个pvList.subList(0,10).clear();}但在压力测试中,如果已满负荷的连续压测,发现会丢掉一些pv,可能是synchronized造成的堵塞导致,如何更好的实现这个需求呢?每10个请求发一次,而后删除,同时可以满足不断累加synchronized放到函数里面估计提升并不大,毕竟add,size,clear方法都必须满足同步需求ConcurrnetLinkedQueue,Concurrent...Array删除、查找的开销都非常大,而且貌似没法用于这种场合p.s.您能留段伪码就最好了
查看完整描述

2 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

publicsynchronizedvoidcountPv(...){
//........生成一个PV对象
pvList.add(PV)
if(pvList.size()>10){
addRedis(pvList.subList(0,10))
}
pvList.subList(0,10).clear();
}
pvList.subList(0,10).clear();这句代码不应该写到if里面吗?既然pvList是static的(类变量),那么countPV也应该是static的才对,这样synchronize使用的锁才会是class,而不是对象。
                            
查看完整回答
反对 回复 2019-05-24
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

不知道你说的满负荷压测时丢pv指的是什么,有没有记录这种情况下,服务器返回的状态码是什么?是因为超时么?如果是因为压力过大超出服务器载能力,换用或其他数据结构也不见得好到哪去,如果想解锁synchronized,可能试试多例模式.每个服务线程创建自己私有的缓存.
                            
查看完整回答
反对 回复 2019-05-24
  • 2 回答
  • 0 关注
  • 401 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信