gpt4 book ai didi

java - 关于 concurrentHashMap 上的程序

转载 作者:行者123 更新时间:2023-11-29 03:36:45 26 4
gpt4 key购买 nike

面试时,面试官问到并发Hash Map及其功能,我详细解释了。他说,在并发HashMap更新操作的情况下,ConcurrentHashMap只锁定了Map的一部分,而不是整个Map。

所以他让我写一个简单的程序来证明,在更新操作中,ConcurrentHashMap 只锁定了Map 的一部分,而不是整个Map。我无法做到这一点,所以请告诉我如何实现这一目标。

最佳答案

面试官可能希望得到一个简单的答案,例如:

  • 如果整个映射对于 get/put 操作是同步的,添加线程不会提高吞吐量,因为瓶颈将是同步块(synchronized block)。然后,您可以使用 synchronizedMap 编写一段代码,表明添加线程没有帮助
  • 因为 map 使用了多个锁,并且假设您的机器上有多个内核,添加线程将提高吞吐量

下面的例子输出如下:

Synchronized one thread: 30
Synchronized multiple threads: 96
Concurrent one thread: 219
Concurrent multiple threads: 142

因此您可以看到,在高竞争(16 个线程)下,同步版本的速度要慢 3 倍以上,而多线程并发版本的速度几乎是单线程的两倍。

同样有趣的是,ConcurrentMap 在单线程情况下具有不可忽略的开销。

这是一个非常人为的例子,由于微基准测试可能会出现所有问题(无论如何都应该丢弃第一个结果)。但它暗示了会发生什么。

public class Test1 {
static final int SIZE = 1000000;
static final int THREADS = 16;
static final ExecutorService executor = Executors.newFixedThreadPool(THREADS);

public static void main(String[] args) throws Exception{

for (int i = 0; i < 10; i++) {
System.out.println("Concurrent one thread");
addSingleThread(new ConcurrentHashMap<Integer, Integer> ());
System.out.println("Concurrent multiple threads");
addMultipleThreads(new ConcurrentHashMap<Integer, Integer> ());
System.out.println("Synchronized one thread");
addSingleThread(Collections.synchronizedMap(new HashMap<Integer, Integer> ()));
System.out.println("Synchronized multiple threads");
addMultipleThreads(Collections.synchronizedMap(new HashMap<Integer, Integer> ()));
}
executor.shutdown();
}

private static void addSingleThread(Map<Integer, Integer> map) {
long start = System.nanoTime();
for (int i = 0; i < SIZE; i++) {
map.put(i, i);
}
System.out.println(map.size()); //use the result
long end = System.nanoTime();
System.out.println("time with single thread: " + (end - start) / 1000000);
}

private static void addMultipleThreads(final Map<Integer, Integer> map) throws Exception {
List<Runnable> runnables = new ArrayList<> ();
for (int i = 0; i < THREADS; i++) {
final int start = i;
runnables.add(new Runnable() {

@Override
public void run() {
//Trying to have one runnable by bucket
for (int j = start; j < SIZE; j += THREADS) {
map.put(j, j);
}
}
});
}
List<Future> futures = new ArrayList<> ();
long start = System.nanoTime();
for (Runnable r : runnables) {
futures.add(executor.submit(r));
}
for (Future f : futures) {
f.get();
}
System.out.println(map.size()); //use the result
long end = System.nanoTime();
System.out.println("time with multiple threads: " + (end - start) / 1000000);
}
}

关于java - 关于 concurrentHashMap 上的程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15118806/

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