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 使用多线程读取30GB文件_Java_Multithreading - Fatal编程技术网

Java 使用多线程读取30GB文件

Java 使用多线程读取30GB文件,java,multithreading,Java,Multithreading,我正在尝试读取一个30GB(2500万行)的大文件。我想写一个代码,它将创建一个线程池,每个线程将并行读取1000行(第一个线程将读取前1000行,第二个线程将读取下一个1000行,依此类推)。 我已经读取了整个文件并创建了线程池,但现在我无法确定如何确保每个线程只读取1000行,并跟踪已读取的行号,以便下一个线程不必读取这些行。A.如果可以访问,则所有线程的行数大致相等,您可以: 假设线程池大小为N,第一个线程寻求文件偏移量0并读取[0,30GB/N],第二个线程寻求偏移量30GB/N,读取[

我正在尝试读取一个30GB(2500万行)的大文件。我想写一个代码,它将创建一个线程池,每个线程将并行读取1000行(第一个线程将读取前1000行,第二个线程将读取下一个1000行,依此类推)。
我已经读取了整个文件并创建了线程池,但现在我无法确定如何确保每个线程只读取1000行,并跟踪已读取的行号,以便下一个线程不必读取这些行。

A.如果可以访问,则所有线程的行数大致相等,您可以:

  • 假设线程池大小为N,第一个线程寻求文件偏移量0并读取[0,30GB/N],第二个线程寻求偏移量30GB/N,读取[30GB/N,30GB/N*2)等
  • 第二个线程可能不在一行的开头,而是在一行的中间。没关系。只需跳过部分行,然后读取整行。第一个线程可能以部分行结束。没关系,只需继续读取,直到读取“\n”。其余线程也会执行相同的操作
  • B.如果所有线程都必须具有精确的euqal行数,即1000行,则可以:

  • 让一个线程读取整个文件,构建索引映射。映射包含诸如line0~line999从偏移量0开始、line1000~line1999从偏移量13521开始等信息
  • 所有线程从相应的偏移量读取文件,并读取1000行
  • 方法A读取文件1次,方法B读取文件2次


    使用方法A或B,您可以让所有线程处理文件(转换、提取、清理..)并行处理。但如果处理速度非常快,则限制为磁盘速度。那么应用程序是IO限制的。您应该只让一个线程读取文件并以串行方式进行处理。

    A.如果可以访问,则所有线程的行数大致相等,您可以:

  • 假设线程池大小为N,第一个线程寻求文件偏移量0并读取[0,30GB/N],第二个线程寻求偏移量30GB/N,读取[30GB/N,30GB/N*2)等
  • 第二个线程可能不在一行的开头,而是在一行的中间。没关系。只需跳过部分行,然后读取整行。第一个线程可能以部分行结束。没关系,只需继续读取,直到读取“\n”。其余线程也会执行相同的操作
  • B.如果所有线程都必须具有精确的euqal行数,即1000行,则可以:

  • 让一个线程读取整个文件,构建索引映射。映射包含诸如line0~line999从偏移量0开始、line1000~line1999从偏移量13521开始等信息
  • 所有线程从相应的偏移量读取文件,并读取1000行
  • 方法A读取文件1次,方法B读取文件2次


    使用方法A或B,您可以让所有线程处理文件(转换、提取、清理..)并行处理。但如果处理速度非常快,则绑定的是磁盘速度。那么应用程序是IO绑定的。您应该只让一个线程读取文件并以串行方式进行处理。

    解决该问题后,您是否使用磁盘驱动器?无论如何,这将是IO绑定。让一个线程读取一个大数据块(30GB)通常比让25000个线程读取小数据块要快。25000个线程的开销很大,如果是一个文件驻留在一个磁盘上,那么每个线程都必须在队列中等待访问时间。通常只有一个线程操作一个外部资源,例如一个文件。与其尝试分发I/O,这将不会提高性能,让读卡器线程将每个捆绑发布到并发队列中,并/或将其发送到执行器任务。如果单个线程上的行处理速度较慢,则可以在一个线程上读取数据,但随后将已读取数据的处理分发到单独的线程。每秒可以读取数百万行使用
    BufferedReader
    ,您应该能够在几秒钟内读取此文件。磁盘不是多线程的,因此添加线程不会加快读取速度。此处的开销不是读取文件,而是您每行必须执行的任何处理。一旦解决了此问题,您是否使用了磁盘驱动器?不管怎样,这都是一个问题将绑定IO。让1个线程读取一个大数据块(30GB)通常比让25000个线程读取小数据块要快。25000个线程的开销很大,如果是一个文件驻留在一个磁盘上,那么每个线程都必须在队列中等待访问时间。通常只有一个线程操作一个外部资源,例如一个文件。与其尝试分发I/O,这将不会提高性能,让读卡器线程将每个捆绑发布到并发队列中,并/或将其发送到执行器任务。如果单个线程上的行处理速度较慢,则可以在一个线程上读取数据,但随后将已读取数据的处理分发到单独的线程。每秒可以读取数百万行使用
    BufferedReader
    ,您应该能够在几秒钟内读取此文件。磁盘不是多线程的,因此添加线程不会使读取速度更快。此处的开销不是读取文件,而是您每行必须执行的任何处理。方法B是我追求的逻辑,但随后遇到了sha问题在线程之间读取的环行号。读取文件的单个线程将文件内容放入一个队列中,然后在读取队列中的特定行的同时维护线程安全计数器以指示行已读。您说“第一个线程将读取前1000行”我认为这组行必须一起处理。如果没有这样的约束,只需读取第一个小N(1,2,ok)行并将其交给第1个线程,第二个小N行交给第2个线程。等等@ChristineDsouza You已经