我打算创建一个实时计数器。因此,一个用户可以递增特定键的计数器值。而另一个通过ajax请求获取更新的计数值(在循环中,或使用一些长轮询方法)。我将使用一个spring控制器,它将注入服务类,我可以做下面的事情,还是有更好的方法:
@Service
public MyService{
//instance variable in spring injected service class, not sure if this correct
static final Map<String, Integer> myMap;
public void add(String key){
Integer count = myMap.get(key);
count++;
myMap.put(key, count);
}
//accessed via ajax loop (and controller), if value changes update display
public Integer getCount(String key){
return myMap.get(key)
}
@PostConstruct
public load(){
myMap = new HashMap<String, Integer>(10){{//initialize}};
}
编辑有几个答案,但不清楚哪个是最好的:同步add方法?在另一个类(带注释的存储库)中创建映射并注入它?还有别的吗?
答案 0 :(得分:2)
您可以,但需要了解这些问题:
答案 1 :(得分:0)
使用ConcurrentHashMap
public void add(String key){
Integer count = myMap.get(key);
count= count++;
myMap.put(key, count);
}
答案 2 :(得分:0)
Integer
类不可变。这意味着您无法对其进行修改。因此,为了增加计数,你必须在增加它后将返回放入地图:
public void add(String key){
Integer count = myMap.get(key);
count++;
myMap.put(key, count);
}
这引入的问题是线程安全性。如果多个线程同时访问此服务类,则必须确保以安全的方式访问其数据。由于myMap
正在被修改,并且因为HashMap
类不是线程安全的,所以必须使其成为线程安全的。一种方法是使用Collections.synchronizedMap()
方法。这将自动使Map实例成为线程安全的。
@PostConstruct
public load(){
myMap = new HashMap<String, Integer>(10){{//initialize}};
myMap = Collections.synchronizedMap(myMap);
}