Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用多线程将多个txt文件读入一个列表?_Java_Multithreading - Fatal编程技术网

Java 如何使用多线程将多个txt文件读入一个列表?

Java 如何使用多线程将多个txt文件读入一个列表?,java,multithreading,Java,Multithreading,我正在学习Java中的多线程。为了练习,我想用多线程并行读取三个txt文件,将每行三个文件添加到一个列表中。这是我的代码: ArrayList<String> allLinesFromFiles= new ArrayList<String>(); Lock blockThread=new ReentrantLock(); Thread t = null; for (String file : files) { t= new Thr

我正在学习Java中的多线程。为了练习,我想用多线程并行读取三个txt文件,将每行三个文件添加到一个列表中。这是我的代码:

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);
ArrayList allLinesFromFiles=new ArrayList();
Lock blockThread=new ReentrantLock();
线程t=null;
用于(字符串文件:文件){
t=新线程(新可运行(){
@凌驾
公开募捐{
试一试{
文件阅读器;
fichero=新文件读取器(文件);
BufferedReader bufferFichero=新的BufferedReader(fichero);
String line=bufferFichero.readLine();
while(行!=null){
writeList(line.toLowerCase());
line=bufferFichero.readLine();
}
bufferFichero.close();
}捕获(IOE异常){
System.out.println(“错误IO”);
}
}
私有无效写列表(字符串行){
blockThread.lock();
allLinesFromFiles.add(行);
blockThread.unlock();
}
});
t、 start();
}
试一试{
t、 join();
}捕捉(中断异常e){
e、 printStackTrace();
}
Collections.sort(allLinesFromFiles);
我在方法“writeList”中使用了lock/unlock(ReentrantLock)进行同步,因为我认为可能需要在ArrayList中写入三个线程。对吗?我必须使用CopyOnWriteArrayList而不是ArrayList吗


我使用join()来等待三个线程的完成,但我的代码无法正常工作。

基于代码的一个简单方法是添加一个
AtomicInteger
计数,以了解读取线程是否结束,主线程等待结束:

List files=Arrays.asList(“a.txt”、“b.txt”、“c.txt”);
ArrayList allLinesFromFiles=新建ArrayList();
Lock blockThread=new ReentrantLock();
AtomicInteger计数=新的AtomicInteger(0);//柜台
线程t=null;
用于(字符串文件:文件){
t=新线程(新可运行(){
@凌驾
公开募捐{
试一试{
文件阅读器;
fichero=newfilereader(getClass().getClassLoader().getResource(file.getFile());
BufferedReader bufferFichero=新的BufferedReader(fichero);
String line=bufferFichero.readLine();
while(行!=null){
writeList(line.toLowerCase());
line=bufferFichero.readLine();
}
bufferFichero.close();
}捕获(IOE异常){
e、 printStackTrace();
System.out.println(“错误IO”);
}最后{
count.getAndIncrement();//计数器++
}
}
私有无效写列表(字符串行){
blockThread.lock();
allLinesFromFiles.add(行);
blockThread.unlock();
}
});
t、 start();
}
while(count.intValue()<3){
时间单位。毫秒。睡眠(500);
}
Collections.sort(allLinesFromFiles);
System.out.println(allLinesFromFiles);
但是,更好的方法是:

List filepath=Arrays.asList(“a.txt”、“b.txt”、“c.txt”);
列表结果=新建ArrayList();
filePath.parallelStream().forEach(filePath->{
试一试{
List strings=Files.readAllLines(
get(ReadTest.class.getClassLoader().getResource(filePath.toURI());
result.addAll(字符串);
}捕获(IOException | URISyntaxException e){
e、 printStackTrace();
}
});
集合。排序(结果);
系统输出打印项次(结果);

您只在一个线程(最后一个文件的线程)上调用了
join()
,因此在对列表进行排序时,并非所有线程都可以完成。您只有一个关键问题—正如Kayaman所说,您只为最后一个线程调用了join()。准备时将所有线程存储在数组/列表中,然后在循环中为每个线程调用.join()。不要像下面建议的那样使用原子计数器和睡眠。Old good.join()非常适合您的情况。第二个小问题是,您应该在finally block中关闭FileReader或使用try-with-resource?