2010-03-02 2 views
3

Я пытаюсь понять, как использовать потоки в моей программе. Прямо сейчас у меня есть однопоточная программа, которая читает один огромный файл. Очень простая программа, просто читается строка за строкой и собирает некоторые статистические данные о словах. Теперь я хотел бы использовать несколько потоков, чтобы сделать это быстрее. Я не уверен, как подойти к этому.Использование многопоточности в Java для чтения данных

Одним из решений является разделение данных на X частей заранее, а затем есть потоки X, каждый из которых работает на одной части одновременно, с одним методом синхронизации для записи статистики в память. Есть ли лучший подход? в частности, я хотел бы избежать предварительного разделения данных заранее.

Спасибо!

+0

Насколько велик ваш файл и какова конфигурация вашей машины? – portoalet

ответ

10

Прежде всего, сделайте некоторое профилирование, чтобы убедиться, что ваш процесс на самом деле связан с вычислением, а не с привязкой ввода/вывода. То есть, ваш сбор статистики медленнее, чем доступ к файлу. В противном случае многопоточность будет медленной вашей программой, а не скоростью, особенно если вы работаете на одноядерном процессоре (или в старинном JVM).

Также подумайте: если ваш файл находится на жестком диске: как вы планируете читать? Вы рискуете добавить задержки на поиск жесткого диска в противном случае, остановив все потоки, которым удалось закончить свой кусок работы, в то время как один поток просит жесткий диск искать позицию 0x03457000 ...

+1

+1 Я должен был найти это с трудом. Процессы, связанные с вводом-выводом, не всегда совместимы с несколькими потоками и могут фактически обеспечивать более низкую производительность, чем однопоточные ввода-вывода. IMO Использование буферизованного чтения/записи обычно ускоряет ввод/вывод на основе диска. – Elister

+0

+1: он никогда не перестает быть правдой - сначала измерьте, затем оптимизируйте. –

2

Вы можете посмотреть на producer-consumer подход. Это классическая проблема с потоками, где один поток создает данные (в вашем случае тот, который читает файл), и записывает его в общий буфер, из которого другой поток считывает данные (потребитель), которые являются вашими потоками вычислений (некоторые Java examples).

Также посмотрите на Javas non-blocking IO.

2

Предположение о том, что доступ многопоточных диск быстрее может быть не так, как disguessed здесь: Directory walker on modern operating systems slower when it's multi-threaded?

Повышение эффективности может быть достигнуто путем чтения расщепления и обработки данных в отдельных потоках.

Но ждите, читайте файлы по очереди? Это не кажется оптимальным. Лучше читать их как поток символов (используя FileReader).

See this sun tutorial.

1

если ваша проблема I/O Bound, может быть, вы можете рассмотреть возможность разделения данных на несколько файлов и положить его в распределенной файловой системы, такие как Hadoop Filesystem (HDFS), а затем запустить Map/Reduce операцию по Это?

+0

Это хороший вариант. Благодарю. – user247866

Смежные вопросы