4

我需要实现线程安全的集群范围计数器映射,所以我使用 Hazelcast 使其集群范围广泛,但不知道如何使其成为线程安全的,我尝试使用 AtomicInteger,但它看起来像一个线程反序列化 AtomicInteger要进行增量,其他线程可能会增加并将其放回地图中。那你能给我一些建议吗?某种最佳实践?我想我可以使用分布式锁来实现它,但不确定它是否是最佳解决方案。

4

2 回答 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 回答