3 回答

TA貢獻(xiàn)1833條經(jīng)驗(yàn) 獲得超4個(gè)贊
在intern'd String上進(jìn)行同步可能根本不是一個(gè)好主意 - 通過實(shí)習(xí),String變成一個(gè)全局對(duì)象,如果你在應(yīng)用程序的不同部分同步interned字符串,你可能會(huì)變得非常奇怪,基本上是不可解決的同步問題,例如死鎖。這似乎不太可能,但是當(dāng)它發(fā)生時(shí),你真的被搞砸了。作為一般規(guī)則,只能在本地對(duì)象上進(jìn)行同步,您絕對(duì)確定模塊外部的代碼不會(huì)鎖定它。
在您的情況下,您可以使用同步哈希表來存儲(chǔ)密鑰的鎖定對(duì)象。
例如:
Object data = StaticCache.get(key, ...);if (data == null) { Object lock = lockTable.get(key); if (lock == null) { // we're the only one looking for this lock = new Object(); synchronized(lock) { lockTable.put(key, lock); // get stuff lockTable.remove(key); } } else { synchronized(lock) { // just to wait for the updater } data = StaticCache.get(key); }} else { // use from cache}
此代碼具有競(jìng)爭(zhēng)條件,其中兩個(gè)線程可能會(huì)將對(duì)象彼此放入鎖定表中。然而,這應(yīng)該不是問題,因?yàn)槟菚r(shí)你只有一個(gè)線程調(diào)用webservice并更新緩存,這應(yīng)該不是問題。
如果您在一段時(shí)間后使緩存失效,則應(yīng)在從鎖定!= null情況下從緩存中檢索數(shù)據(jù)后再檢查數(shù)據(jù)是否為空。
或者,更容易,您可以使整個(gè)緩存查找方法(“getSomeDataByEmail”)同步。這意味著所有線程在訪問緩存時(shí)都必須進(jìn)行同步,這可能是性能問題。但是一如既往,首先嘗試這個(gè)簡(jiǎn)單的解決方案,看看它是否真的是一個(gè)問題!在許多情況下它不應(yīng)該是,因?yàn)槟赡芑ㄙM(fèi)更多時(shí)間處理結(jié)果而不是同步。
添加回答
舉報(bào)