第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

在Java中同步String對(duì)象

在Java中同步String對(duì)象

蝴蝶刀刀 2019-07-24 19:40:51
在Java中同步String對(duì)象我有一個(gè)webapp,我正在進(jìn)行一些負(fù)載/性能測(cè)試,特別是在我們希望有幾百個(gè)用戶訪問同一頁(yè)面并在此頁(yè)面上每10秒點(diǎn)擊一次刷新的功能。我們發(fā)現(xiàn)我們可以使用此功能進(jìn)行改進(jìn)的一個(gè)方面是在一段時(shí)間內(nèi)緩存來自Web服務(wù)的響應(yīng),因?yàn)閿?shù)據(jù)沒有變化。在實(shí)現(xiàn)這個(gè)基本緩存之后,在一些進(jìn)一步的測(cè)試中,我發(fā)現(xiàn)我沒有考慮并發(fā)線程如何同時(shí)訪問Cache。我發(fā)現(xiàn)在大約100毫秒內(nèi),大約有50個(gè)線程試圖從Cache中獲取對(duì)象,發(fā)現(xiàn)它已經(jīng)過期,命中Web服務(wù)以獲取數(shù)據(jù),然后將對(duì)象放回緩存中。原始代碼看起來像這樣:private SomeData[] getSomeDataByEmail(WebServiceInterface service, String email) {   final String key = "Data-" + email;   SomeData[] data = (SomeData[]) StaticCache.get(key);   if (data == null) {       data = service.getSomeDataForEmail(email);       StaticCache.set(key, data, CACHE_TIME);   }   else {       logger.debug("getSomeDataForEmail: using cached object");   }   return data;}因此,為了確保在對(duì)象key過期時(shí)只有一個(gè)線程正在調(diào)用Web服務(wù),我認(rèn)為我需要同步Cache get / set操作,并且似乎使用緩存鍵是一個(gè)很好的候選對(duì)象同步(這樣,對(duì)電子郵件b@b.com的此方法的調(diào)用不會(huì)被方法調(diào)用a@a.com阻止)。我將方法更新為如下所示:private SomeData[] getSomeDataByEmail(WebServiceInterface service, String email) {   SomeData[] data = null;   final String key = "Data-" + email;   synchronized(key) {           data =(SomeData[]) StaticCache.get(key);     if (data == null) {         data = service.getSomeDataForEmail(email);         StaticCache.set(key, data, CACHE_TIME);     }     else {       logger.debug("getSomeDataForEmail: using cached object");     }   }   return data;}我希望在get / set操作周圍一次只能看到一個(gè)線程進(jìn)入/退出同步塊。在String對(duì)象上同步是否存在問題?我認(rèn)為緩存鍵是一個(gè)很好的選擇,因?yàn)樗鼘?duì)于操作是唯一的,即使final String key在方法中聲明,我也認(rèn)為每個(gè)線程都會(huì)獲得對(duì)同一個(gè)對(duì)象的引用,因此會(huì)同步單個(gè)對(duì)象。我在這做錯(cuò)了什么?
查看完整描述

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é)果而不是同步。


查看完整回答
反對(duì) 回復(fù) 2019-07-24
  • 3 回答
  • 0 關(guān)注
  • 347 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)