Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread safe counter map in Hazelcast

Tags:

java

hazelcast

I need to implement thread-safe cluster wide counter map, so I use Hazelcast to make it cluster wide, but don't know how to make it thread-safe, I tried to use AtomicInteger, but it looks like while one thread deserialize AtomicInteger to make increment, other thread may increment and put it already back in map. So can you make some advice for me? Some sort of best practice? I think i can implement it using distributed locks, but not sure that it is best solution.

like image 494
mulya Avatar asked Feb 16 '23 07:02

mulya


1 Answers

I did it using Hazelcast Distributed Task, I've implemented PartitionAware interface so this code will be executed on the node whe counter located, so all distributed operations (lock, get, put, unlock) will be executed locally and this should enable higher concurrency.

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);
    }
}
like image 101
mulya Avatar answered Feb 17 '23 21:02

mulya