首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用多线程读取单个文件:应该加快速度吗?

用多线程读取单个文件:应该加快速度吗?
EN

Stack Overflow用户
提问于 2012-01-11 04:14:28
回答 3查看 25.2K关注 0票数 7

我正在读取一个包含500000行的文件。我正在测试多线程是如何加速进程的……

代码语言:javascript
复制
private void multiThreadRead(int num){

    for(int i=1; i<= num; i++) { 
        new Thread(readIndivColumn(i),""+i).start(); 
     } 
}

private Runnable readIndivColumn(final int colNum){
    return new Runnable(){
        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {

                long startTime = System.currentTimeMillis();
                System.out.println("From Thread no:"+colNum+" Start time:"+startTime);

                RandomAccessFile raf = new RandomAccessFile("./src/test/test1.csv","r");
                String line = "";
                //System.out.println("From Thread no:"+colNum);

                while((line = raf.readLine()) != null){
                    //System.out.println(line);
                    //System.out.println(StatUtils.getCellValue(line, colNum));
                }


                long elapsedTime = System.currentTimeMillis() - startTime;

                String formattedTime = String.format("%d min, %d sec",  
                        TimeUnit.MILLISECONDS.toMinutes(elapsedTime), 
                        TimeUnit.MILLISECONDS.toSeconds(elapsedTime) -  
                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsedTime)) 
                    );

                System.out.println("From Thread no:"+colNum+" Finished Time:"+formattedTime);
            } 
            catch (Exception e) {
                // TODO Auto-generated catch block
                System.out.println("From Thread no:"+colNum +"===>"+e.getMessage());

                e.printStackTrace();
            }
        }
    };
}

private void sequentialRead(int num){
    try{
        long startTime = System.currentTimeMillis();
        System.out.println("Start time:"+startTime);

        for(int i =0; i < num; i++){
            RandomAccessFile raf = new RandomAccessFile("./src/test/test1.csv","r");
            String line = "";

            while((line = raf.readLine()) != null){
                //System.out.println(line);
            }               
        }

        long elapsedTime = System.currentTimeMillis() - startTime;

        String formattedTime = String.format("%d min, %d sec",  
                TimeUnit.MILLISECONDS.toMinutes(elapsedTime), 
                TimeUnit.MILLISECONDS.toSeconds(elapsedTime) -  
                TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsedTime)) 
            );

        System.out.println("Finished Time:"+formattedTime);
    }
    catch (Exception e) {
        e.printStackTrace();
        // TODO: handle exception
    }

}
    public TesterClass() {

    sequentialRead(1);      
    this.multiThreadRead(1);

}

对于num =1,我得到以下结果:

开始时间:1326224619049

完成时间:2分14秒

顺序读取结束...........

多线程启动:

从线程编号:1开始时间:1326224753606

从线程编号:1开始完成时间:2分13秒

多线程结束.....

对于num =5,我得到以下结果:

代码语言:javascript
复制
    formatted Time:10 min, 20 sec

Sequential read ENDS...........

Multi-Thread read starts:

From Thread no:1 Start time:1326223509574
From Thread no:3 Start time:1326223509574
From Thread no:4 Start time:1326223509574
From Thread no:5 Start time:1326223509574
From Thread no:2 Start time:1326223509574
From Thread no:4 formatted Time:5 min, 54 sec
From Thread no:2 formatted Time:6 min, 0 sec
From Thread no:3 formatted Time:6 min, 7 sec
From Thread no:5 formatted Time:6 min, 23 sec
From Thread no:1 formatted Time:6 min, 23 sec
Multi-Thread read ENDS.....

我的问题是:多线程读取不应该花费大约。2.13秒?你能解释一下为什么多线程解决方案花了这么长时间吗?

提前谢谢。

EN

回答 3

Stack Overflow用户

发布于 2012-01-11 04:26:40

并行读取时速度变慢的原因是因为磁性硬盘磁头需要为每个线程寻找下一个读取位置(大约需要5ms)。因此,使用多线程读取有效地使磁盘在寻道之间反弹,从而减慢其速度。从单个磁盘读取文件的唯一推荐方法是使用一个线程顺序读取。

票数 10
EN

Stack Overflow用户

发布于 2012-01-11 04:17:08

由于文件读取主要是等待磁盘I/O,因此会出现磁盘旋转速度不快的问题,因为它被许多线程使用:)

票数 8
EN

Stack Overflow用户

发布于 2012-01-11 04:20:13

从文件读取数据本质上是一个串行过程,假设没有缓存,这意味着从文件检索数据的速度是有限制的。即使没有文件锁定(例如,以只读方式打开文件),第一个之后的所有线程都会在磁盘上阻塞读取,所以你让所有其他线程等待,当数据变得可用时,任何一个处于活动状态的线程都会处理下一个块。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8809894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档