[英]Java Multithreading with Opening Files
我有一個txt文件: order_me.txt
,其中有一些整數需要使用4個線程進行排序。 他們需要同時工作,但不能做同樣的事情。 我已經設法對整數進行排序,但是某些方法無法正常工作...
這是線程類:
public class Threading {
static List<Integer> integersCopy = new ArrayList<>();
public static void main(String[] args) {
openFile();
Thread t1 = new Thread(new Command("thread 1", integersCopy));
t1.start();
Thread t2 = new Thread(new Command("thread 2", integersCopy));
t2.start();
Thread t3 = new Thread(new Command("thread 3", integersCopy));
t3.start();
Thread t4 = new Thread(new Command("thread 4", integersCopy));
t4.start();
try {
if (t1.isAlive())
t1.join();
if (t2.isAlive())
t2.join();
if (t3.isAlive())
t3.join();
if (t4.isAlive())
t4.join();
} catch (Exception e) {
System.out.println("Exception with threads");
}
}
public static void openFile() {
File file = new File("order_me.txt");
try {
Scanner scanner = new Scanner(file);
List<Integer> integers = new ArrayList<>();
while (scanner.hasNext()) {
if (scanner.hasNextInt()) {
integers.add(scanner.nextInt());
} else {
scanner.next();
}
}
integersCopy = integers;
System.out.println("File opened successfully");
} catch (Exception e) {
System.out.println("Triggered exception");
}
}
這是排序類:
import java.util.Collections;
import java.util.List;
public class Command implements Runnable {
String threadName;
List<Integer> listOfInts;
Command(String name, List<Integer> list) {
threadName = name;
listOfInts = list;
}
@Override
public void run() {
for (int i = 0; i < listOfInts.size(); i++) {
Collections.sort(listOfInts);
System.out.print(+listOfInts.get(i) + " ");
}
}
}
一旦一個線程對整數進行了排序,就沒有必要在多個線程中嘗試執行相同的操作,事實上,由於這樣做不是以線程安全的方式進行的,因此很可能破壞列表。
簡而言之,使用一個線程。
您正在變異幾個線程上的共享List
。 ArrayList
不是線程安全的 :您需要使用線程安全的Collection
或使用Collections.synchronizedList
。
而且,如果您在每個線程中對相同的列表進行排序,那么您的實現可能是錯誤的:
Thread
的目的:划分工作。 另外,您可以使用Stream
來做到這一點:
parallel()
方法使Stream
使用多個線程。 ForkJoinPool
用於使用另一個線程池(請參見此SO答案 )。 舉個例子來說可能沒有用。 Scanner
不能轉換為IntStream
或Stream
。 您需要使用Files.lines
和Pattern
來按空格( \\s+
)分隔行。 flatMapToInt
將OptionalInt
轉換為IntStream
(對於無效數字,該IntStream
將為空,例如*a4
)。 sorted()
確保我們使用默認排序進行排序。 使用比較器進行排序將需要正常的Stream,因此,將flatMapToInt
更改為flatMap
。 toArray()
可能比在第二個示例中使用Integer
ArrayList
更好。 使用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();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.