当前位置: 首页 > 知识库问答 >
问题:

Hazelcast中的线程安全计数器映射

徐帅
2023-03-14

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

共有1个答案

叶茂才
2023-03-14

我是使用Hazelcast分布式任务完成的,我实现了partitionaware接口,所以这段代码将在计数器所在的节点上执行,所以所有分布式操作(lock、get、put、unlock)都将在本地执行,这应该能够实现更高的并发性。

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);
    }
}
 类似资料:
  • 问题内容: 我从一个非常简单的多线程示例开始。我试图做一个线程安全的计数器。我想创建两个线程,使计数器间歇地增加到1000。以下代码: 据我所知,while循环现在意味着只有第一个线程才能访问计数器,直到达到1000。输出: 我该如何解决?如何获得共享计数器的线程? 问题答案: 两个线程都可以访问您的变量。 您看到的现象称为线程饥饿。输入代码的受保护部分后(很抱歉,我之前错过了它),其他线程将需要

  • 问题内容: 我需要一个线程安全映射,我有类似这样的内容:(我对Java很陌生) 问题答案:

  • 如何在C#中获得性能最佳的线程安全计数器? 这很简单: 但有更快的替代方案吗?

  • 我读过这个主题:C#线程安全快速(est)计数器,并在我的并行代码中实现了这个特性。据我所知,这一切都很好,但它大大增加了处理时间,大约10%。 这让我有点担心,我认为问题在于我做了大量相对便宜的产品( 现在,我看不到解决的办法,但也许我错过了一些明显的东西。我甚至在考虑使用n个计数器(对应于并行化程度),然后在特定的核上增加每个计数器,但这似乎不可行(检测我在哪个核上可能会更昂贵,更不用说复杂的

  • 当使用名为的全局整数作为计数器时,以下代码可以正常工作: 我基本上是使用作为每次调用函数时的递增计数器。计数器第一次执行时会被分配一个起始位置。我之所以使用全局变量,是因为我想确保每次传递的ID都准确增加,而不管执行是否进入递归调用。调用此函数(第一次…)来自分配全局变量起始位置的ForEach循环 我的目标是在初始调用中使用一个并行的。Foreach而不是常规的For per循环。我的问题是处理

  • 在Master Hazelcast电子书“17.4.1.分区感知操作”下,它指出: 要执行分区感知操作,需要创建操作线程数组。 单个操作线程对多个分区执行操作; 每个分区只属于1个操作线程。 忽略备份和近缓存,当我创建一个IMap实例时,这是否意味着我只能有一个并发的put/get操作在整个集群的每个map分区上执行?进一步说,如果我附加了一个MapStore,这是否意味着我只能对我的后端数据库运