7 回答

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超3個(gè)贊
public synchronized void countPv(...){
//........生成一個(gè)PV對(duì)象
pvList.add(PV)
if(pvList.size() > 10){
addRedis(pvList.subList(0,10))
}
pvList.subList(0,10).clear();
}
pvList.subList(0,10).clear();
這句代碼不應(yīng)該寫到 if 里面嗎?
既然 pvList 是 static
的(類變量),那么 countPV 也應(yīng)該是 static
的才對(duì),這樣 synchronize
使用的鎖才會(huì)是 class,而不是對(duì)象。

TA貢獻(xiàn)1719條經(jīng)驗(yàn) 獲得超6個(gè)贊
不知道你說(shuō)的滿負(fù)荷壓測(cè)時(shí)丟pv指的是什么,有沒(méi)有記錄這種情況下,服務(wù)器返回的狀態(tài)碼是什么?是因?yàn)槌瑫r(shí)么?
如果是因?yàn)閴毫^(guò)大超出服務(wù)器載能力,換用或其他數(shù)據(jù)結(jié)構(gòu)也不見(jiàn)得好到哪去, 如果想解鎖synchronized, 可能試試多例模式. 每個(gè)服務(wù)線程創(chuàng)建自己私有的緩存.

TA貢獻(xiàn)1966條經(jīng)驗(yàn) 獲得超4個(gè)贊
@fengdui 有一句評(píng)論說(shuō)得好,Redis操作要搬出去。
方法一:
// 把10個(gè)元素return出去讓外面的調(diào)用者去調(diào)Redis,別占用同步塊的時(shí)間
public synchronized List<Object> countPv(...) {
...
}
方法二:開個(gè)線程池去異步發(fā)Redis,但是機(jī)器重啟會(huì)丟失來(lái)不及發(fā)送的數(shù)據(jù)
if (pvList.size() > 10) {
//前10個(gè)打包成任務(wù)扔給線程池
senderExecutor.execute(new SendTask(new ArrayList<>(pvList.subList(0,10)))); //當(dāng)場(chǎng)復(fù)制了subList
pvList.subList(0,10).clear(); //這行要移到這里,這可能就是你丟數(shù)據(jù)的原因
}
添加回答
舉報(bào)