gpt4 book ai didi

Java ConcurrentHashMap

转载 作者:行者123 更新时间:2023-11-30 07:35:01 26 4
gpt4 key购买 nike

在一个应用程序中,1 个线程负责不断更新映射,主线程定期读取映射,使用 ConcurrentHashmap 是否足够?或者我应该明确地锁定同步块(synchronized block)中的操作吗?任何解释都会很棒。

更新

我有一个映射的 getter 和 setter(封装在自定义类型中),两个线程可以同时使用它们,ConcurrentHashMap 仍然是一个好的解决方案吗?或者我应该同步 getter/setter(或者声明实例变量为 volatile)?只是想确保这个额外的细节不会改变解决方案。

最佳答案

只要您在对并发 HashMap 的一个方法调用中执行所有操作,就不需要使用额外的锁定。不幸的是,如果您需要以原子方式执行多个方法,则必须使用锁定,在这种情况下使用并发 HashMap 没有帮助,您还不如使用普通的 HashMap。

@James 的建议让我开始思考调整不需要的并发性是否会使 ConcurrentHashMap 更快。它应该减少内存,但你需要有成千上万的内存才能产生很大的不同。所以我编写了这个测试,并且您总是需要调整并发级别似乎并不明显。

warmup: Average access time 36 ns.
warmup2: Average access time 28 ns.
1 concurrency: Average access time 25 ns.
2 concurrency: Average access time 25 ns.
4 concurrency: Average access time 25 ns.
8 concurrency: Average access time 25 ns.
16 concurrency: Average access time 24 ns.
32 concurrency: Average access time 25 ns.
64 concurrency: Average access time 26 ns.
128 concurrency: Average access time 26 ns.
256 concurrency: Average access time 26 ns.
512 concurrency: Average access time 27 ns.
1024 concurrency: Average access time 28 ns.

代码

    public static void main(String[] args) {
test("warmup", new ConcurrentHashMap());
test("warmup2", new ConcurrentHashMap());
for(int i=1;i<=1024;i+=i)
test(i+" concurrency", new ConcurrentHashMap(16, 0.75f, i));
}

private static void test(String description, ConcurrentHashMap map) {
Integer[] ints = new Integer[2000];
for(int i=0;i<ints.length;i++)
ints[i] = i;
long start = System.nanoTime();
for(int i=0;i<20*1000*1000;i+=ints.length) {
for (Integer j : ints) {
map.put(j,1);
map.get(j);
}
}
long time = System.nanoTime() - start;
System.out.println(description+": Average access time "+(time/20/1000/1000/2)+" ns.");
}

正如@bestss 指出的那样,较高的并发级别可能会较慢,因为它具有较差的缓存特性。

编辑:除了@betsss 的关注之外,如果没有方法调用,循环是否会得到优化。这是三个循环,都相同但迭代次数不同。他们打印

10M: Time per loop 661 ps.
100K: Time per loop 26490 ps.
1M: Time per loop 19718 ps.
10M: Time per loop 4 ps.
100K: Time per loop 17 ps.
1M: Time per loop 0 ps.

.

{
int loops = 10*1000 * 1000;
long product = 1;
long start = System.nanoTime();
for(int i=0;i< loops;i++)
product *= i;
long time = System.nanoTime() - start;
System.out.println("10M: Time per loop "+1000*time/loops+" ps.");
}
{
int loops = 100 * 1000;
long product = 1;
long start = System.nanoTime();
for(int i=0;i< loops;i++)
product *= i;
long time = System.nanoTime() - start;
System.out.println("100K: Time per loop "+1000*time/loops+" ps.");
}
{
int loops = 1000 * 1000;
long product = 1;
long start = System.nanoTime();
for(int i=0;i< loops;i++)
product *= i;
long time = System.nanoTime() - start;
System.out.println("1M: Time per loop "+1000*time/loops+" ps.");
}
// code for three loops repeated

关于Java ConcurrentHashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4786967/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com