我正在使用类型的对象
Map<Long, Map<UUID, OperationEntry>> stepOperations = new ConcurrentHashMap<>();
以控制某些操作的执行。我有一个Kafka消息处理器方法,在接收到关于操作状态更改的消息时,需要根据传递的UUID在stepOperationsMap中查找和更新记录的状态。
UUID类未被覆盖(standatdjava.util.UUID)。
如果Map中存在screenshot中清晰可见的键“3102869 c-7653- 4fb 7-ad 47-a629 b5 cbac 90”,那么从containsKey方法中获得意外结果的原因是什么?
下面是代码中有问题的部分:
private OperationEntry getOperationLogEntry(UUID requestId) {
return stepOperations.values().stream()
.filter(value -> value.containsKey(requestId))
.map(value -> value.get(requestId))
.findFirst()
.orElse(null);
}
使用ConcurrentHashMap类是因为它保证支持多线程处理。传入的Kafka消息由一个由16个线程组成的线程池处理。
内部Map的存在会是一个潜在的问题吗?
简单测试,如
Map<UUID, String> testMap = new java.util.concurrent.ConcurrentHashMap<>();
UUID key = UUID.randomUUID();
testMap.put(key, "testValue");
if (testMap.containsKey(key)) {
System.out.println(testMap.get(key));
}
就像预期的那样工作
2条答案
按热度按时间col17t5w1#
在调试器中,我们可以看到
HashMap
中的value
变量。不是ConcurrentHashMap
:当你使用多级Map时,你应该使用
computeIfAbsent
。从你的代码中,你可能应该:
stepOperations
成为ConcurrentMap<Long, ConcurrentMap<UUID, Whatever>>
,以确保两个级别都是好的。computeIfAbsent
,如stepOperations.computeIfAbsent(key, ignored -> new ConcurrentHashMap<>())
要添加新步骤,请执行以下操作:
最后,你可以重写你的代码:
这样做,而不是:
两点:
id
确保使用相同的idConcurrentHashMap
禁止键和值为null
:containsKey
在这里是无用的。jogvjijk2#
感谢您的回复。事实上,取代
与
在这种情况下,内部Map也必须是并发的。