Многопоточный доступ к файлу - PullRequest
11 голосов
/ 19 ноября 2008

У нас есть многопоточная Java-программа. Многопоточность будет записывать в файл, и один поток будет читать из этого файла. Я ищу некоторые дизайнерские идеи. Нужна ли синхронизация?

Ответы [ 7 ]

5 голосов
/ 20 ноября 2008

FileChannel теоретически безопасен для потоков. Из Javadoc:

Файловые каналы безопасны для использования несколькими параллельными потоками. Метод close может быть вызван в любое время, как указано в Channel интерфейс. Только одна операция, которая включает в себя позицию канала или может изменить размер своего файла, может выполняться в любой момент времени; пытается инициировать вторую такую ​​операцию, пока первая еще Выполняется блокировка до завершения первой операции. Другой операции, в частности те, которые занимают явную позицию, могут действовать одновременно; действительно ли они так делают, зависит от базовая реализация и, следовательно, не определена.

Если вы можете использовать их, тогда вы можете использовать встроенную синхронизацию, вместо того, чтобы писать свою собственную.

5 голосов
/ 19 ноября 2008

Я бы рассмотрел синхронизацию в этом случае. Представьте, что 2 потока (t1 и t2) открывают файл одновременно и начинают запись в него. Изменения, выполненные первым потоком, перезаписываются вторым потоком, потому что второй поток является последним, чтобы сохранить изменения в файле. Когда поток t1 записывает в файл, t2 должен подождать, пока t1 завершит свою задачу, прежде чем он сможет его открыть.

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

2 голосов
/ 19 ноября 2008

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

1 голос
/ 19 ноября 2008

Если вам нужно несколько считывателей и один писатель, вам потребуется Read Write Lock или Read Write Mutex.

Но вам нужно несколько писателей и один читатель. Как вы знаете, эти авторы не будут перезаписывать данные друг друга? Они как-то разделены?

0 голосов
/ 27 января 2010

Синхронизация необходима в этом случае. FileChannel полезен для предотвращения изменения файлов процессами вне JVM: не так для приложений, которые включают в себя несколько потоков, записывающих в один файл. Из (далее) JavaDoc для FileChannel:

Блокировки файлов хранятся от имени вся виртуальная машина Java. Они есть не подходит для контроля доступа к файл несколькими потоками внутри та же виртуальная машина.

См. в этом посте для краткого обсуждения стратегий для совместного использования записи файлов между потоками.

0 голосов
/ 19 ноября 2008

Вам нужна синхронизация (блокировка), если у вас есть смесь читателей и писателей или писателей и писателей. Если у вас есть только читатели, вам не нужна синхронизация.

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

0 голосов
/ 19 ноября 2008

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

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

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