java中的多线程文件读取开销

时间:2014-04-15 13:04:46

标签: java multithreading io

我有一台服务器,在处理器,存储吞吐量和内存方面拥有大量资源,可以处理大量文件。

我正在做一些性能测试并且已经调整了一个小的java程序来测试并行读取。编码在下面

import java.io.*;
import java.lang.*;
class MultiThreadedFileRead extends Thread
{
        InputStream in;
        MultiThreadedFileRead(String fname) throws Exception
        {
                in=new FileInputStream(fname);
                this.start();
        }
        public void run()
        {
                int i=0;
                while(i!=-1)
                {
                        try
                        {
                            i=in.read();
                            //System.out.print((char)i);
                                                        continue;
                        }catch(Exception e){}
                }
                try
                {
                        in.close();
                }catch(Exception e){}
        }
        public static void main(String a[]) throws Exception
        {
                int n=[0];
                MultiThreadedFileRead fr[]=new MultiThreadedFileRead[n];
                long tim;
                tim=System.currentTimeMillis();
                for(int i=1;i<n;i++)
                        fr[i]=new MultiThreadedFileRead(a[i]);
                for(int i=1;i<n;i++)
                {
                        try
                        {
                                fr[i].join();
                        }catch(Exception e){}
                }
                System.out.println("Time Required : "+(System.currentTimeMillis()-tim)+" miliseconds.");
        }
}

结果似乎有所纠正:并行读取10个文件(10个线程)与读取一个文件/一个线程加上一些开销几乎相同。 (抱歉,我在这里没有实际的数字,可能会稍后编辑添加)

可以肯定的是,我想知道的是预期会是什么,或者#34;合理的&#34;打开并行读取线程的开销......?

另外,我是一名java开发人员,所以虽然程序非常简单,如果我出错了,请指出。

PS。运行程序我有10x10mb文件(名为tf0,tf1,tf2等),我运行测试为java MultiThreadedFileRead 10 tf*(10个线程)。

3 个答案:

答案 0 :(得分:0)

我认为问题可能是 IO本身不是多线程的

如果您创建 X 线程并且它们都发出 IO 上的读取,那么它将 X 快一倍,因为它会执行IO读取顺序。

我测试了9个线程和1个线程文件(每个100MB)的代码。结果是208秒和94秒。

我看到测试有两个问题:

  1. 不缓冲(逐字节)读取并不能获得最大吞吐量。
  2. 您正在测试中创建n-1个线程。

答案 1 :(得分:0)

研究启动线程所需的时间没有意义,主要有两个原因:

  1. 与阅读文件所需的时间相比,这是无关紧要的 - 除非你有一些认真授权的系统。
  2. 您收集的统计信息将特定于您正在测试的系统 - 将其移至另一个系统,在炎热/寒冷的日子运行,您的统计信息将毫无意义。
  3. 如果您正在寻求真正的性能提升,那么最好调查实际在多台计算机上分发流程。

答案 2 :(得分:0)

如果这是一台服务器,您应该使用线程池而不是重新创建线程。这将消除线程创建开销(除了一次),并且会在请求太多时阻止服务器关闭。

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html

此外,您可能需要考虑非阻塞io,以获得真正的性能提升。

http://tutorials.jenkov.com/java-nio/nio-vs-io.html

使用正常读取时,如@mrVoid建议的那样,您应该使用缓冲读取器。

你可能想要引入一些缓存机制。