我已经完成了一些代码以将包含对[String,Integer],示例的并行集合组合在一起
线程1 [Car,1] [Bear,1] [Car,1]
线程2 [River,1] [Car,1] [River,1]
结果应该是每个唯一对密钥的集合(按字母顺序排序)
[熊,1]
[汽车,1] [汽车,1] [汽车,1]
[River,1] [River,1] [River,1]
我执行此操作的解决方案如下所示,但是有时我没有得到预期的结果,或者从包含结果集合的列表中抛出了ConcurrentModificationException
List<Collection<Pair<String, Integer>>> combiningResult = new ArrayList<>();
private void startMappingPhase() throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss.SSS");
Invoker invoker = new Invoker(mappingClsPath, "Mapping", "mapper");
List<Callable<Integer>> tasks = new ArrayList<>();
for (String line : fileLines) {
tasks.add(() -> {
try {
combine((Collection<Pair<String, Integer>>) invoker.invoke(line));
} catch (Exception e) {
e.printStackTrace();
executor.shutdownNow();
errorOccurred = true;
return 0;
}
return 1;
});
if (errorOccurred)
Utils.showFatalError("Some error occurred, See log for more detalis");
}
long start = System.nanoTime();
System.out.println(tasks.size() + " Tasks");
System.out.println("Started at " + formatter.format(new Date()) + "\n");
executor.invokeAll(tasks);
long elapsedTime = System.nanoTime() - start;
partitioningResult.forEach(c -> {
System.out.println(c.size() + "\n" + c);
});
System.out.print("\nFinished in " + (elapsedTime / 1_000_000_000.0) + " milliseconds\n");
}
private void partition(Collection<Pair<String, Integer>> pairs) {
Set<Pair<String, Integer>> uniquePairs = new LinkedHashSet<>(pairs);
for (Pair<String, Integer> uniquePair : uniquePairs) {
int pFrequencyCount = Collections.frequency(pairs, uniquePair);
Optional<Collection<Pair<String, Integer>>> collResult = combiningResult.stream().filter(c -> c.contains(uniquePair)).findAny();
if (collResult.isPresent()) {
collResult.ifPresent(c -> {
for (int i = 0; i < pFrequencyCount; i++)
c.add(uniquePair);
});
} else {
Collection<Pair<String, Integer>> newColl = new ArrayList<>();
for (int i = 0; i < pFrequencyCount; i++)
newColl.add(uniquePair);
combiningResult.add(newColl);
}
}
}
我尝试了坚持ArrayList的CopyOnWriteList,但有时它得到的结果不完整,例如
[Car,1] [Car,1]坚持三个问题,我的问题
有没有一种方法可以实现我要尝试的操作而不会出现ConcurrentModificationException和不完整的结果?
答案 0 :(得分:0)
如果您试图从多个线程修改单个集合,则需要添加一个同步块或使用支持并发性的JDK类之一。这些通常比同步块执行得更好。
https://docs.oracle.com/javase/tutorial/essential/concurrency/collections.html