2 回答
TA贡献1827条经验 获得超9个赞
一旦一个线程对整数进行了排序,尝试在多个线程中做同样的事情就没有意义了,事实上,因为这不是以线程安全的方式完成的,你很可能会破坏列表。
简而言之,使用一个线程。
TA贡献1735条经验 获得超5个赞
您正在改变List多个线程上的共享。ArrayList不是线程安全的:您需要使用线程安全Collection或使用Collections.synchronizedList.
如果您在每个线程中对相同的列表进行排序,那么您的实现可能是错误的:
您应该在父线程中阅读一次列表
您应该按线程数拆分列表,并对每个自己的线程中的每个子列表进行排序。这就是
Thread在这种情况下的目的:分工去做。然后您应该在父线程中加入子列表:在加入过程中,您将不得不进行排序。由于每个子列表都已排序,因此您可以使用更快的排序(例如:如果子列表 A 的第一个项目在子列表 B 的最后一个之后,那么您可以将 A 的所有项目添加到 B 中)或标准排序。
此外,您可能Stream会这样做:
该
parallel()方法是Stream使用多个线程的原因。ForkJoinPool用于使用另一个线程池(请参阅此 SO 答案)。举个例子可能没用。遗憾的是,
Scanner不能转换为IntStream或Stream。您需要使用Files.lines和 aPattern用空格 (\s+)分割行。我们使用
flatMapToInt要转换为IntStream的OptionalInt(这将是空的无效数字,例如:*a4)。sorted()确保我们使用默认排序进行排序。使用比较器进行排序需要一个普通的 Stream,因此,将flatMapToInt其更改为flatMap.toArray()在这种情况下可能比在第二个示例中使用ArrayListof更好Integer。
使用 Java 11 测试的代码:
public static void main(final String[] args) throws Exception {
final Pattern splitter = Pattern.compile("\\s+");
// see
//
final ForkJoinPool forkJoinPool = new ForkJoinPool();
final Future<int[]> future = forkJoinPool.submit(() -> {
try (final Stream<String> lines = Files.lines(Paths.get("myfile.txt"), StandardCharsets.UTF_8)) {
return lines.parallel() // use default parallel ExecutorService
.flatMap(splitter::splitAsStream) // tokenize input
.flatMapToInt(s -> parseInt(s).stream()) // convert to number (eg: nextInt())
.sorted().toArray();
}
});
final int[] result = future.get();
System.out.println("result.length: " + result.length);
// Arrays.stream(result).forEach(System.out::println);
final Future<List<Integer>> future2 = forkJoinPool.submit(() -> {
try (Stream<String> lines = Files.lines(Paths.get("myfile.txt"), StandardCharsets.UTF_8)) {
return lines.parallel() // use default parallel ExecutorService
.flatMap(splitter::splitAsStream) // tokenize input
.flatMapToInt(s -> parseInt(s).stream()) // convert to number (eg: nextInt())
.sorted().collect(ArrayList::new, List::add, List::addAll) // probably best to use
// array.
;
}
});
final List<Integer> result2 = future2.get();
System.out.println("result2.length: " + result2.size());
}
static OptionalInt parseInt(final String s) {
try {
return OptionalInt.of(Integer.parseInt(s));
} catch (final NumberFormatException e) {
return OptionalInt.empty();
}
}
添加回答
举报
