多线程—用java从一个大文件中读取并写入多个文件

mbyulnm0  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(624)

我有一个从1到100000000的100000000条记录的a.txt文件,每条记录是一行。我必须先读取文件a,然后再写入文件b和c,只要偶数行写入文件b,奇数行写入文件c。所需的读写时间必须小于40秒。下面是我已经拥有的代码,但是运行时需要超过50秒。有没有其他方法可以减少运行时间?
线程.java

import java.io.*;
import java.util.concurrent.LinkedBlockingQueue;

public class Threading implements Runnable {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    String file;
    Boolean stop = false;

    public Threading(String file) {
        this.file = file;
    }

    public void addQueue(String row) {
        queue.add();
    }

    public void Stop() {
        stop = true;
    }

    public void run() {
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(file));
            while(!stop) {
                try {
                    String rơ = queue.take();
                    bw.while(row + "\n");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

线程创建.java
//我用两个线程来写两个文件b和c

import java.io.*;
import java.util.List;

public class ThreadCreate {
    public void startThread(File file) {
        Threading t1 = new Threading("B.txt");
        Threading t1 = new Threading("B.txt");
        Thread td1 = new Thread(t1);
        Thread td1 = new Thread(t1);
        td1.start();
        td2.start();

        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line;
            long start = System.currentTimeMillis();
            while ((line = br.readLine()) != null) {
                if (Integer.parseInt(line) % 2 == 0) {
                    t1.addQueue(line);
                } else {
                    t2.addQueue(line);
                }
            }
            t1.Stop();
            t2.Stop();
            br.close();
            long end = System.currentTimeMillis();
            System.out.println("Time to read file A and write file B, C: " + ((end - start)/1000) + "s");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

主.java

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        File file = new File("A.txt");

        //Write file B, C
        ThreadCreate t = new ThreadCreate();
        t.startThread(file);
    }
}
kcwpcxri

kcwpcxri1#

你为什么要做线?那只会让事情变慢。如果瓶颈要么是计算本身,要么是操作的阻塞性质,那么线程是有用的,如果不是,线程只会造成伤害。在这里,情况并非如此:cpu只是处于空闲状态(瓶颈将是磁盘),而其阻塞的性质意味着多线程也没有帮助:告诉单个ssd并行写入2船字节可能不会更快(只是更慢,因为它需要来回反弹)。如果目标磁盘是一个旋转的磁盘,那么速度就慢多了——写入头无法使自己的克隆速度更快,而通过使其成为多线程的方式,要求写入头在不同的写入位置之间来回跳转就浪费了大量的时间。
没有什么能立即让我感觉到显著加速的时机已经成熟。
有时,将大量数据写入磁盘只需50秒。如果不能接受,请购买速度更快的磁盘。

lymnna71

lymnna712#

尝试内存Map文件

byte[] buffer = "foo bar foo bar text\n".getBytes();
int number_of_lines = 100000000;

FileChannel file = new RandomAccessFile("writeFIle.txt", "rw").getChannel();
ByteBuffer wrBuf = file.map(FileChannel.MapMode.READ_WRITE, 0, buffer.length * number_of_lines);
for (int i = 0; i < number_of_lines; i++)
{
    wrBuf.put(buffer);
}
file.close();

花了我的电脑(戴尔,i7处理器,带ssd,32gbram)半分钟多一点来运行这个代码)

相关问题