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);
    }
}

}

现在,当我启动服务器时,创建的模型是一个单例 bean。当有人调用端点时,我希望能够修改模型的哈希图

/增量

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

synchronized目前,当我添加关键字时,此 incrementPageRequest 不是线程安全的,该方法变为线程安全的,但我听说同步的成本非常高,我正在寻找高吞吐量和性能。

在不同步和保持高性能的情况下如何实现相同的目标?

更新

尝试使用 Concurrent HashMap 仍然失败我正在使用 Jmeter 测试对 api 的并发调用

我如何更改此逻辑以使其在并发哈希图中起作用

 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);
       }
4

1 回答 1

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 次。

关于您的第二个问题“我如何更改此逻辑以使其在并发哈希图中起作用”更改此:

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

也:

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

将私有字段保留为接口可以让您更简单地更改地图的实现。

于 2017-06-17T10:27:56.403 回答