Чтение большого файла и обработка многопоточностью - PullRequest
0 голосов
/ 08 октября 2019

Я пытаюсь прочитать большой (в ГБ) файл со строками JSON, выполнить некоторую «обработку» и записать результат в другой файл. Я буду использовать потоковый API GSON для этой цели. Чтобы ускорить обработку, я бы хотел многопоточность части 'обработка'. Я читаю файл построчно, так как не могу загрузить весь файл в память. Моя «обработка» зависит от двух разных строк (возможно, тысяч строк), которые удовлетворяют определенным условиям. Возможно ли многопоточность этой «обработки», не загружая все это в память?

Ответы [ 2 ]

1 голос
/ 08 октября 2019

Любые предложения о том, как это сделать?

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

  • Поток читателя читает файл JSON, используя потоковый API 1 . Когда он определил единицу работы, которая должна быть выполнена, он создает задачу и передает ее в службу исполнителя и повторяет ее.

  • Сервер-исполнитель обрабатывает поставленные им задачи. Вам следует использовать службу с ограниченным пулом потоков и, возможно, с ограниченной / блокирующей рабочей очередью.

  • Поток модуля записи сканирует Future объекты, созданные при отправке задачи, и использует их дляполучить результаты задачи (по порядку), сгенерировать вывод из результатов и записать вывод в файл.

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

1 - Если вы этого не сделаете, то: 1) вам нужно уметьпроанализировать и сохранить весь входной файл в памяти, и 2) поток чтения не сможет начать отправлять задачи, пока не закончит анализ ввода.

2 - Сделайте этоесли это упрощает вещи, а не по причинам производительности. Необходимость взаимного исключения во время записи убивает любые гипотетические преимущества в производительности.


Как отмечает @Thilo, мало что можно получить, если попытаться создать несколько потоков чтения. (И очень много сложностей, если вы попробуете!)

1 голос
/ 08 октября 2019

Я думаю, что у вас будет один процесс чтения из файла, который добавляет рабочих (Runnable / Callable) в очередь. Затем у вас есть пул потоков, который потребляет из очереди и выполняет рабочих параллельно.

См. Executors статические методы, которые могут помочь при создании ExecutorService

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...