【发布时间】:2021-02-17 07:13:58
【问题描述】:
我正在学习 Java 中的多线程。为了练习,我想做多线程并行读取三个txt文件,将三个文件的每一行添加到一个List中。这是我的代码:
ArrayList<String> allLinesFromFiles= new ArrayList<String>();
Lock blockThread=new ReentrantLock();
Thread t = null;
for (String file : files) {
t= new Thread(new Runnable() {
@Override
public void run() {
try {
FileReader fichero;
fichero = new FileReader(file);
BufferedReader bufferFichero = new BufferedReader(fichero);
String line = bufferFichero.readLine();
while (line != null) {
writeList(line.toLowerCase());
line = bufferFichero.readLine();
}
bufferFichero.close();
}catch (IOException e) {
System.out.println("Error IO");
}
}
private void writeList(String line) {
blockThread.lock();
allLinesFromFiles.add(line);
blockThread.unlock();
}
});
t.start();
}
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Collections.sort(allLinesFromFiles);
我在方法“writeList”中使用了锁定/解锁(ReentrantLock)来同步,因为我认为可能需要三个线程写入 ArrayList。是正确的?我是否应该使用 CopyOnWriteArrayList 而不是 ArrayList?
我使用 join() 来等待三个线程的完成,但我的代码不能正常工作。
【问题讨论】:
-
您只在一个线程(最后一个文件的线程)上调用
join(),因此当您对列表进行排序时,并非所有线程都已完成。 -
您只有一个关键问题 - 正如 Kayaman 所说,您只为最后一个线程调用 join()。在准备时将所有线程存储在一个数组/列表中,然后在循环/for each 中调用 .join() foe 每个线程。不要使用下面建议的 AtomicCounters 和 sleeps。旧好的 .join() 非常适合您的情况。第二个小问题是您应该在 finally 块中关闭 FileReader 或使用 try-with-resource。
标签: java multithreading