Чтение одного файла с несколькими потоками: нужно ускорить?

Я читаю файл, который содержит 500000 строк. Я тестирую, как несколько потоков ускоряют процесс....

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 секунд

Последовательное чтение ENDS...........

начинается чтение нескольких потоков:

От темы потока: 1 Время начала: 1326224753606

Из темы темы: 1 Время окончания: 2 мин, 13 сек.

Multi-Thread читает ENDS.....

для num = 5 Я получаю следующий результат:

    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 с? Не могли бы вы объяснить, почему это слишком долго с многопоточным решением?

Спасибо заранее.

Ответ 1

Так как чтение файла в основном ожидает ввода/вывода диска, у вас есть проблема, что диск не будет вращаться быстрее, потому что он используется многими потоками:)

Ответ 2

Причина, по которой вы наблюдаете замедление при параллельном чтении, заключается в том, что головке жесткого диска необходимо искать следующую позицию чтения (около 5 мс) для каждого потока. Таким образом, чтение с несколькими потоками эффективно отскакивает диск между запросами, замедляя его. Единственный рекомендуемый способ чтения файла с одного диска - последовательно читать один поток.

Ответ 3

Чтение из файла - это последовательный последовательный процесс, предполагающий отсутствие кеширования, то есть существует ограничение на то, как быстро вы можете извлекать данные из файла. Даже без блокировок файлов (т.е. Открытие файла только для чтения) все потоки после 1-го будут просто блокироваться на диске, чтобы вы делали все остальные потоки ожидающими, и в зависимости от того, какой из них активен, когда становятся доступными данные, это тот, который обрабатывает следующий блок.