【问题标题】:multithreading to read a file in Java多线程在Java中读取文件
【发布时间】:2013-09-24 02:18:41
【问题描述】:

我正在创建线程来读取 java 中的文件。当我创建 2 个线程时,每个线程都会读取整个文件,而我希望它们读取文件的不同部分。我尝试输入 sleep()、join()、yield(),但在包含它们之后,它只会减慢读取速度。

public class MyClass implements Runnable {

    Thread thread;
    public MyClass(int numOfThreads) {
        for(int i=0;i < numOfThreads; i++) {
            thread = new Thread(this);
            thread.start();
        }
    }

    public void run() {
        readFile();
    }
}

在 readFile 中,在 while 循环中(逐行读取)我调用了 sleep()/yield()。如何让线程读取文件的不同部分?

更新了用于读取文件的方法...

public synchronized void readFile() {
    try {
        String str;
        BufferedReader buf = new BufferedReader(new FileReader("read.txt");
        while ((line = buf.readLine()) != null) {
            String[] info = str.split(" ");
            String first name = info[0];
            String second name = info[1];
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
        }  catch (IOException e) {
        System.out.println("Error : File not found");
        e.printStackTrace();
    }
}

【问题讨论】:

  • 读取文件的代码在哪里?
  • 公共同步 void readFile() { try{ String str; BufferedReader buf = new BufferedReader(new FileReader("read.txt"); while((line=buf.readLine())!=null) { String[] info = str.split(" "); String first name = info [0]; String second name = info[1]; try{ Thread.sleep(100); } catch(InterruptedException e) { } } catch(IOException e){ System.out.println("Error : File not found" ); e.printStackTrace(); } }
  • 您可以使用RandomAccessFile 读取文件中的任意位置,但它不理解“行”。要查找行,您必须扫描整个文件,因为换行可能位于数据中的任何位置。除非是结构化数据。
  • 你实际上想用这个来完成什么?
  • 您已经可以使用BufferedReader 每秒读取数百万行。这已经足够快了。是什么让您认为多线程会使其更快?

标签: java multithreading


【解决方案1】:

我想你在想用这样的多线程读取文件会比用一个线程读取要快。这几乎肯定是错误的。线程在使用多个内核或处理器的 CPU 密集型任务上获得更好的性能。但文件读取不是 CPU 密集型任务。

操作系统使用磁盘控制器以磁盘接口的全带宽读取字节。对于几乎任何硬件组合,速度都受磁盘(读取和/或寻道时间)、它的控制器和它的 DMA 接口或总线的限制,而不是由 CPU 决定。 CPU 很容易让磁盘控制器保持 100% 忙碌,甚至不同磁盘的多个控制器也是如此。如果您需要证明这一点,请启动一个大文件副本并观察 CPU 利用率。不会很高。

因此,在您的多个线程中,一次只会运行一个,从而增加了单线程计算的开销。

做什么缓慢的文件传输是缓冲。为了获得灵活性,i/o 库最终可以将每个字符缓冲 2 次甚至 3 次。

Java NIO 库旨在尽可能多地消除这种开销。参见例如this article。类似的还有很多。我的经验是,精心编写的 NIO 阅读器将使用硬件的大部分可用性能。

有一个警告:如果您设置了重型病毒检查器来扫描您正在阅读的文件类型,它可能会使读取 CPU 受限。在这种不寻常的情况下,您可能会通过多线程获得提升,具体取决于检查器架构。在这种情况下,您会找到总文件大小 S 并让线程 k=0,1,..,n-1 从偏移量 kS/n 读取到 (k+1)S/n - 1 (by seeking向右偏移和跟踪每个线程中读取的字节数)。但是我仍然强烈怀疑额外的磁头寻道时间和随机访问的其他影响将抵消在多线程中运行病毒检查程序的任何优势。

【讨论】:

    【解决方案2】:

    在你的程序中 string.split(" ") 会导致运行速度变慢。自己写,速度提升6倍。 这样的事情会有所帮助:

    int index = vcf_record_string.indexOf("\t");
    vcf_record_string.substring(0, index)
    

    如果您的系统支持高吞吐量 I/O,您可以这样做: How to read a file using multiple threads in Java when a high throughput(3GB/s) file system is available

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-02
      • 2017-11-27
      • 1970-01-01
      • 2011-12-28
      相关资源
      最近更新 更多