@bakomchik

Как с помощью java реализовать блокировку файла в файловой системе, для использования в многопоточном коде?

Проблема:
Взаимодействие с внешней системой осуществляется через файловую систему(smb).
Есть папка на файловой системе, в которую необходимо записывать файлы, далее OUTBOX. Для синхронизации доступа к OUTBOX используется файл - семафор( далее -- semFile).
Писатели(мы), для того что бы записать файл в OUTBOX должны получить блокировку на файл semFile.
Читатели(внешняя система) для чтения должны получить блокировку на файл semFile.
Количество писателей заранее не известно. Запись ведется в произвольное время, многопоточно и довольно часто.
Чтение происходит в произвольное время.
Если блокировка на файл уже взята одним потоком, другие потоки не должны пытаться взять эту блокировку, а сразу писать в OUTBOX.
Блокоровка не может быть отпущена до тех пор пока все писатели не закончат запись файлов в OUTBOX.

Ограничение -- java 6.
Собственно вопрос:
Подскажите,есть ли какие нибудь бибилиотеки с реализацией необходимого функционала или хотя бы похожего на него?
Может кто-нибудь писал подобные вещи и может поделиться опытом(я новичок в concurrency) ?
Если все таки придется писать собственный велосипед, просьба подсказать куда смотреть.
Спасибо.
  • Вопрос задан
  • 3808 просмотров
Решения вопроса 1
pi314
@pi314
Президент Солнечной системы и окрестностей
Дело в том, что гарантии блокировки файла дает (или НЕ дает), собственно, файловая система, а Ява просто довольствуется тем, что есть. Существует две принципиально разные идеологии: либо блокировка ФС таки блокирует (как в Винде), либо она носит скорее информативно-предупреждающий характер (как в Линуксе). Обе - со своими плюсами и минусами.

В Яве есть механизм доступа к этому делу, в java.nio.channels.FileLock, но что и как с его помощю удастся реализовать, прямо зависит от платформы.

В связи с этим, для решения указанной задачи существует два подхода.

Кривой, исторически-обусловленный, используется, например, в HL7 (где проблема интероперабельности разных платформ через ФС все еще актуальна) определена иная семантика семафорных файлов: семафорный файл создается ПОСЛЕ того, как файл данных освобожден пишущим процессом (т.е. наличие семафора является гарантией ОТСУТСТВИЯ блокировки). Это элементарно реализуется на Яве созданием семафорного файла во временной папке с последующим move в целевую, ибо атомарность move-а гарантируется ФС. Недостаток этого подхода в том, что на однажды освобожденный файл нельзя повторно получить блокировку, в связи с чем вся эта костыльная кухня практически не масштабируется.

Правильное, более универсальное и масштабируемое решение - вообще не использовать ФС в качестве shared memory (которая для этого, строго говоря, и не предназначена), а соединять процессы через брокер с внятным протоколом (очередь сообщений, сокеты, БД в конце концов).

Так что, если это возможно, рекомендую попытаться решить проблему на уровне переосмысления общей архитектуры системы. Если нет, то придется клепать свой платформозависимый велосипед из java.nio.* и java.util.concurrent.* (например ReentrantLock)... т.е., фактически, переизобретать эдак добрую треть JEE :)

P.S. Кстати, если это чудо должно еще и поверх smb крутиться, то я бы, лично, лучше сразу завернулся в простыню и пополз на кладбище, т.к. от smb с сетью в этом деле можно поиметь под нагрузкой еще как минимум столько же удовольствия.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@Lol4t0
Никак. Самба не даст гарантий на блокировку.

Нужна надежная система с интерфейсом ФС - используйте zookerper
Ответ написан
@moryakov
Блокоровка не может быть отпущена до тех пор пока все писатели не закончат запись файлов в OUTBOX

имхо, исходя из этого условия напрашивается очередь писателей..
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Bell Integrator Ульяновск
До 400 000 ₽
Bell Integrator Хабаровск
До 400 000 ₽
Bell Integrator Ижевск
До 400 000 ₽