- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用 ConcurrentHashMap,我发现 computeIfAbsent 比 putIfAbsent 慢两倍。这里是简单的测试:
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
public class Test {
public static void main(String[] args) throws Exception {
String[] keys = {"a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a0", "a01", "a02", "a03", "a04", "a05", "a06", "a07", "a08", "a09", "a00"};
System.out.println("Test case 1");
long time = System.currentTimeMillis();
testCase1(keys);
System.out.println("ExecutionTime: " + String.valueOf(System.currentTimeMillis() - time));
System.out.println("Test case 2");
time = System.currentTimeMillis();
testCase2(keys);
System.out.println("ExecutionTime: " + String.valueOf(System.currentTimeMillis() - time));
System.out.println("Test case 3");
time = System.currentTimeMillis();
testCase3(keys);
System.out.println("ExecutionTime: " + String.valueOf(System.currentTimeMillis() - time));
}
public static void testCase1(String[] keys) throws InterruptedException {
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
List<Thread> threads = new ArrayList<>();
for (String key : keys) {
Thread thread = new Thread(() -> map.computeIfAbsent(key, s -> {
System.out.println(key);
String result = new TestRun().compute();
System.out.println("Computing finished for " + key);
return result;
}));
thread.start();
threads.add(thread);
}
for (Thread thread : threads) {
thread.join();
}
}
public static void testCase2(String[] keys) throws InterruptedException {
List<Thread> threads = new ArrayList<>();
for (String key : keys) {
Thread thread = new Thread(() -> {
System.out.println(key);
new TestRun().compute();
System.out.println("Computing finished for " + key);
});
thread.start();
threads.add(thread);
}
for (Thread thread : threads) {
thread.join();
}
}
public static void testCase3(String[] keys) throws InterruptedException {
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
List<Thread> threads = new ArrayList<>();
for (String key : keys) {
Thread thread = new Thread(() -> {
Callable<String> c = () -> {
System.out.println(key);
String result = new TestRun().compute();
System.out.println("Computing finished for " + key);
return result;
};
try {
map.putIfAbsent(key, c.call());
} catch (Exception e) {
e.printStackTrace(System.out);
}
});
thread.start();
threads.add(thread);
}
for (Thread thread : threads) {
thread.join();
}
}
}
class TestRun {
public String compute() {
try {
Thread.currentThread().sleep(5000);
} catch (Exception e) {
e.printStackTrace(System.out);
}
return UUID.randomUUID().toString();
}
}
在我的笔记本电脑上运行这个测试,testCase1(使用 computeIfAbsent())的执行时间是 10068ms,testCase2(执行相同的东西但没有将其包装到 computeIfAbsent())的执行时间是 5009ms(当然它会有所不同有点,但主要趋势就是这样)。最有趣的是 testCase3 - 它与 testCase1 几乎相同(除了使用 putIfAbsent() 而不是 computeIfAbsent()),但它的执行速度快了两倍(testCase3 为 5010ms,testCase1 为 10068ms)。
查看源代码,computeIfAbsent() 和 putVal()(在底层的 putIfAbsent() 中使用)几乎相同。
有人知道是什么导致线程执行时间不同吗?
最佳答案
您遇到记录的功能:
Some attempted update operations on this map by other threads may be blocked while computation is in progress, so the computation should be short and simple, and must not attempt to update any other mappings of this map.
computeIfAbsent 检查键是否存在并锁定 map 的某些部分。然后它调用仿函数并将结果放入映射(如果返回值不为空)。只有在那之后这部分 map 才被解锁。
另一方面,test3总是调用c.call(),计算结束后调用putIfAbsent。
关于java - 为什么 ConcurrentHashMap::putIfAbsent 比 ConcurrentHashMap::computeIfAbsent 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40081456/
我有一个 Hashmap,在其中维护不同类型的读取器到它们各自的 java 类实现的映射。我有一个多线程 Java 服务器,支持 32 种类型的阅读器。 您可以假设每 30 秒,每种类型的读取器都会有
Java 8 中引入了一个新的 computeIfAbsent API。ConcurrentHashMap's impelementation of it 的 javadocs状态: If the s
在本文中,我们将学习 Java ConcurrentHashMap 类的 computeIfAbsent() 方法。找到 computeIfAbsent 方法的 Java 文档。 V computeI
computeIfAbsent 是 java.util.Map 的默认方法,已在 Java 8 中引入。当与指定键关联的值不可用或为 null 时,computeIfAbsent 方法起作用,在这种情
我有这样的代码: ConcurrentMap map = new ConcurrentHashMap<>(); AtomicBoolean isNew = new AtomicBoolean(fals
java.util.HashMap 的文档明确指出:“如果多个线程同时访问一个 HashMap ,并且至少有一个线程在结构上修改了该映射,则它必须在外部进行同步。” 但是,请考虑使用映射作为缓存以减少
升级到 Android Studio 3 Canary 4 后出现此错误: Gradle sync failed: Argument for @NotNull parameter 'key' of c
考虑以下某种固定大小缓存的实现,它允许通过整数句柄进行查找: static class HandleCache { private final AtomicInteger counter =
我是 Java 的新手,有点从 C# 过渡到 Java。 java.util.function有一个定义为 Function 的接口(interface)这是输入到 computeIfAbsent M
于是我对 Java 的 Map computeIfAbsent 产生了好奇。 (使用 java8)方法,我希望有人能告诉我为什么会这样,因为我无法真正理解该问题背后的逻辑。 所以,我有一个带有键的映射
我很想用Map.computeIfAbsent但是距离本科生的lambda已经太久了。 几乎直接来自文档:它提供了一个旧方法的示例: Map whoLetDogsOut = new Concurren
我正在尝试制作具有以下功能的工厂: 它应该总是返回一个 Filter 对象。 从 hashmap = 如果字符串字母(键)已经存在于 hashmap 中,它应该只从 hashmap 中获取它的值(对象
我有以下代码,它是一个玩具代码,但可以重现该问题: import java.util.*; import java.util.concurrent.ConcurrentHashMap; import
ConcurrentHashMap#computeIfAbsent 中的 Javadoc 说 The computation should be short and simple, and must
整个方法调用是原子的还是只是 BiFunction 执行的原子?是阻塞所有键还是只阻塞同一键上的调用? 最佳答案 以下详细信息适用于 OpenJDK Java 11。 这三种方法持有 Node 的锁在
我正在练习 Cay S. Horstmann 所著的“Java SE 8 for the really Impatient”一书的练习。有 2 个练习要求相同算法的不同实现,一个使用 merge ,其
我正在使用 ConcurrentHashMap在 Scala 中,我想使用 computeIfAbsent()方法,但无法弄清楚第二个参数的语法。有人可以告诉我什么是正确的语法吗? 运行以下代码时 v
有没有办法模拟ConcurrentHashmap.computeIfAbsent但不将条目分配给hashmap。我只需要当 HashMap 中的条目尚不存在时该方法生成的实例。这些都在线程中运行。所以
我有一组非常适合我的代码: for (String word : distinctWordsInOneLigne) { Map> map = new H
大家好,我想知道如何在不使用 lambda 表达式的情况下使用 JSONObject.computeIfAbsent 。实际上,这是我的代码 list.computeIfAbsent(id, k ->
我是一名优秀的程序员,十分优秀!