0

我有有不同的變量模型。增加值?

public class Model implements Serializable{ 

    public final static int STATE_INIT = 0; 
    public final static int STATE_READY = 1; 

    private Integer state = STATE_INIT; 
    private HashMap<Integer,Integer>pageRequests = new HashMap<>(); 
    private HashMap<Integer,Integer>impr = new HashMap<>(); 
    private HashMap<Integer,Integer>clicks = new HashMap<>(); 

    public void incrementPageRequests(int accountId){ 

    if(this.pageRequests.get(accountId) != null){ 
     this.pageRequests.put(accountId,this.pageRequests.get(accountId) +1); 
    } else { 
     this.pageRequests.put(accountId,1); 
    } 
} 

public void incrementImprServed(int accountId){ 

    if(this.imprServed.get(accountId) != null){ 
     this.imprServed.put(accountId,this.imprServed.get(accountId) +1); 
    } else { 
     this.imprServed.put(accountId,1); 
    } 
} 

public void incrementClicksServed(int accountId){ 

    if(this.clicksServed.get(accountId) != null){ 
     this.clicksServed.put(accountId,this.clicksServed.get(accountId) +1); 
    } else { 
     this.clicksServed.put(accountId,1); 
    } 
} 

}

現在,當我開始創建模型的服務器是一個singleton bean。我希望能夠修改模型的HashMap中,當有人呼叫端點

/增量

@GetMapping(path = "/increment") 
    public String increment(){ 
     model.incrementPageRequests(1); 
     return "Okay"; 
    } 

目前,當我加入​​關鍵字的方法這incrementPageRequest不是線程安全變得線程安全,但我聽說同步是非常昂貴的,我正在尋找高吞吐量和性能。

我怎麼能不acheive同步並保持高性能的一樣嗎?

更新

試圖與併發HashMap和它仍然失敗,我使用的JMeter測試併發調用的API

如何改變這個邏輯,這樣它在併發的HashMap

if(this.pageRequests.get(accountId) != null){ 
      this.pageRequests.put(accountId,this.pageRequests.get(accountId) +1); 
     } else { 
      System.out.println("Here"); 
      this.pageRequests.putIfAbsent(accountId,1); 
     } 
+0

同步是MOT '非常昂貴'。如果你認爲這將是一個瓶頸,你需要獲得一些證據。 ''ConcurrentHashMap'不會'失敗',除非你有編碼錯誤。不清楚你在問什麼。 – EJP

+0

你認爲'synchronized'將會成爲這個REST調用中的* slow *部分嗎?真? – Nim

+0

我不確定它是否嘗試將hashmap更改爲併發hashmap,但它不起作用。你能讓我這樣,我需要改變我的方法嗎? @EJP – INFOSYS

回答

0

起初:創建一個基準,決定解決方案是什麼幫助你。

而且你在這裏做了一些多餘的工作(以及其他方法太):

if(this.pageRequests.get(accountId) != null){ 
    this.pageRequests.put(accountId,this.pageRequests.get(accountId) +1); 
} else { 
    this.pageRequests.put(accountId,1); 
} 

相反

final String value = this.pageRequests.get(accountId); 
if(value == null){ 
    this.pageRequests.put(accountId, 1); 
    return; 
} 
this.pageRequests.put(accountId, value + 1); 

現在你將有1讀取訪問地圖少。

關於你提到的第二個問題:「我如何改變這個邏輯,這樣它在併發HashMap的」更改此:

private HashMap<Integer, Integer> pageRequests = new HashMap<>(); 

太:

private Map<Integer, Integer> pageRequests = new ConcurrentHashMap<>(); 

保持私有字段作爲界面允許您更簡單改變地圖的執行。

+0

它拋出一個空指針execption在啓動時,pagerequesthashmap爲空即使嘗試不解決問題 – INFOSYS

+0

即使將其更改爲Integer,然後運行,如果我正在觸發500個併發請求,增量值爲434,因爲它應該是500 – INFOSYS