我们最近在我的工作中讨论过我们是否需要使用ConcurrentHashMap,或者我们是否可以在多线程环境中使用常规HashMap.HashMaps的参数是两个:它比ConcurrentHashMap快,所以我们应该尽可能使用它.并且ConcurrentModificationException显然只有当你在修改时迭代Map时出现,所以"如果我们只从地图中PUT和GET,那么常规HashMap的问题是什么?" 是争论.
我认为并发PUT操作或并发PUT和READ可能会导致异常,所以我组合了一个测试来证明这一点.测试很简单; 创建10个线程,每个线程将相同的1000个键值对一次又一次地写入地图5秒钟,然后打印生成的地图.
结果实际上很混乱:
Length:1299
Errors recorded: 0
Run Code Online (Sandbox Code Playgroud)
我认为每个键值对在HashMap中都是唯一的,但是通过查看地图,我可以找到多个相同的Key-Value对.我期待某种异常或损坏的键或值,但我没想到这一点.这是怎么发生的?
这是我使用的代码,供参考:
public class ConcurrentErrorTest
{
static final long runtime = 5000;
static final AtomicInteger errCount = new AtomicInteger();
static final int count = 10;
public static void main(String[] args) throws InterruptedException
{
List<Thread> threads = new LinkedList<>();
final Map<String, Integer> map = getMap();
for (int i = 0; i < count; i++)
{
Thread t = getThread(map);
threads.add(t);
t.start();
}
for (int i = 0; i < …Run Code Online (Sandbox Code Playgroud) 我今天遇到了这个,我无法理解正在发生的事情.
目的是创建一个可以更改参数对象的匿名方法.我虽然想出了一种智能的方法来传递值并在不同对象之间修改它们而没有对另一个对象的明确知识,但是有些事情是错误的.以下代码概述了一般问题:
void foo() {
String a = "foo";
MethodMap.addMethod("1", new Method() {
@Override
public void execute(Object ... args) {
args[0] = "bar";
}
} );
MethodMap.invoke("1", a);
System.out.println(a);
}
class MethodMap {
private static Map<String, Invocation> map = new HashMap<>();
public static boolean addMethod(String key, Invocation method) {
map.put(key, method);
}
public static void invoke(String key, Object ... args){
map.get(key).execute(args);
}
}
public interface Invocation {
public void execute(Object ... args);
}
Run Code Online (Sandbox Code Playgroud)
我的意图是这个代码应该输出bar,但它输出foo.我不太确定为什么.是不是通过引用传递了Java对象?在那种情况下,我不应该修改它们吗?
有人可以解释一下我错过了什么吗?
我对该领域术语的了解可能实际上限制了我在网上搜索这个术语的能力,因为我不知道谷歌会说些什么. …