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