我需要实现线程安全的群集宽计数器映射,所以我使用Hazelcast使其成为群集范围,但不知道如何使其成为线程安全的,我尝试使用AtomicInteger,但它看起来像一个线程反序列化AtomicInteger进行增量,其他线程可以递增并将其放回映射中。你能为我提一些建议吗?某种最佳做法?我想我可以使用分布式锁实现它,但不确定它是最好的解决方案。
答案 0 :(得分:7)
我是使用Hazelcast分布式任务完成的,我已实现PartitionAware
接口,因此此代码将在计数器所在的节点上执行,因此将执行所有分布式操作(锁定,获取,放置,解锁)在本地,这应该能够实现更高的并发性。
public void track(final ip) {
try {
if(ip != null) {
executor.execute(new IncrementCounterDistributedTask<>(ip, IP_MAP_NAME));
}
} catch (RejectedExecutionException ignored) {
}
}
private static class IncrementCounterDistributedTask<K> implements Runnable, PartitionAware, Serializable {
private final K key;
private final String mapName;
public IncrementCounterDistributedTask(K key, String mapName) {
this.key = key;
this.mapName = mapName;
}
@Override
public Object getPartitionKey() {
return key;
}
@Override
public void run() {
IMap<K, Integer> map = Hazelcast.getMap(mapName);
map.lock(key);
Integer counter = map.get(key);
if(counter == null) {
map.put(key, 1);
} else {
map.put(key, ++counter);
}
map.unlock(key);
}
}
答案 1 :(得分:1)
我知道这有点旧,但它在我的搜索中成为最佳结果。
我会考虑以下内容。
IAtomicLong counter = client.getAtomicLong("nameOfCounter");
Long incrementedValue = counter.incrementAndGet();