我需要实现线程安全的集群范围计数器映射,所以我使用 Hazelcast 使其集群范围广泛,但不知道如何使其成为线程安全的,我尝试使用 AtomicInteger,但它看起来像一个线程反序列化 AtomicInteger要进行增量,其他线程可能会增加并将其放回地图中。那你能给我一些建议吗?某种最佳实践?我想我可以使用分布式锁来实现它,但不确定它是否是最佳解决方案。
问问题
3344 次
2 回答
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);
}
}
于 2013-09-14T11:13:08.863 回答
1
我知道这有点旧,但它在我的搜索中排名第一。
我会考虑以下几点。
IAtomicLong counter = client.getAtomicLong("nameOfCounter");
Long incrementedValue = counter.incrementAndGet();
于 2018-01-08T11:06:19.500 回答