2016-03-24 2 views
0

Мне нужно было бы прочитать файл эффективным способом.Как читать из разных разделов файла, используя несколько потоков в java, и будет ли он эффективным?

Я бы прочитал файл, и каждое слово из прочитанного файла просмотрело бы пользовательский словарь и решило бы смещение слова в файле.

я придумал следующее решение для этого

Producer нить

Читает строку за строкой из файла и помещает каждую строку ConcurrentHashMap.

Потребительские темы

Читает строку из карты и смотрит в словарь на слово.

Я абсолютно уверен в реализации потребителя, но не уверен, что использование потоков для чтения файла было бы полезно. Неуверенный об использовании Java IO или Java NIO

Обновленный образец кода для чтения из файла обновления, чтобы карта для производителя

public class DocumentManager { 


    Map<Location, String> map = null; 


    public DocumentManager(Map<Location, String> map) { 
     this.map = map; 
    } 

    public void readFile(String path) throws IOException{ 
     BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(path))); 

     String line = ""; 

     while((line = bufferedReader.readLine()) != null){ 
      map.put(new Location(0, 0), line); 
      //location is dummy at the moment 
     } 
    } 

} 
+1

Что вы подразумеваете под «эффективным»? Многопоточная программа является «менее эффективной», чем однопоточная программа, если «эффективный» означает наилучшее использование циклов ЦП, но многопоточная программа, работающая на многопроцессорном хосте, может быть более эффективной, чем однопоточная программа, если «эффективный» означает получение работы в минимальном количестве в реальном времени. –

+1

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

+0

Это в основном бессмысленно. Диск не является многопоточным. Дни дисков с фиксированными дисками с несколькими головками - это несколько десятилетий назад. Вы можете читать миллионы строк в секунду с помощью «BufferedReader». Если этого недостаточно, ничего нет. – EJP

ответ

0

Использование потоков не является бесплатным, и передача объекта между потоками через блокирующую очередь может быть удивительно дорогостоящей. Однако обновление Карты, хотя и не бесплатное, намного дешевле, чем передача работы между потоками.

Скорее всего, вы потратите большую часть своего времени на чтение и разбор файла. Если у вас есть текстовый файл, это очень сложно сделать с помощью нескольких потоков, и даже сложнее сделать это быстрее, чем просто читать его в одном потоке.

+0

Хорошо. Допустим, что один поток читает строку за раз, помещенную в ConcurrentHashMap, и пользователи будут читать с карты. Думаю, это может сделать трюк –

+1

@ChannammaVadigeri, что бы потребители сделали, что производитель не может сделать? Вы можете просто обновить карту с нужным результатом. –

+0

то, что я думал, readLine в классе bufferedReader будет блокироваться до тех пор, пока строка не будет прочитана, я думал, что могу использовать это время процессора для обработки в разных потоках. Я совершенно новичок в java, поэтому, пожалуйста, извините, если какие-либо неправильные заявления я сделал. Просто обновление с образцом кода, который у меня в голове –

0

Вы можете использовать RandomAccessFile в каждом потоке, чтобы прочитать различные разделы файла. RandomAccessFile позволяет читать байты, начиная с указателя файла, и продвигать указатель файла за считанные байты.

+0

Это ответ или комментарий? –

+1

Вам нужно будет убедиться, что вы читаете целые слова, даже если вы начинаете наугад. Вам также необходимо убедиться, что вы обновили локальную копию подсчета и только слились в конце, но это можно было бы сделать. –