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()
在這種情況下可能比在第二個示例中使用ArrayList
of更好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();
}
}
添加回答
舉報