Я работаю на многопоточном сервере на Java.Сервер контролирует каталог файлов.Клиенты могут попросить сервер:
- загрузить файл из каталога сервера
- , чтобы загрузить новую версию уже существующего файла на сервер, перезаписав старую версию на сервере.directory.
Для выполнения переносов я планирую использовать FileChannels и SocketChannels, используя методы TransferFrom и TransferTo.Согласно документации, эти два метода являются потокобезопасными.Дело в том, что одного вызова этих двух функций может быть недостаточно для полного чтения / записи файла.
Проблема возникает, если к одному и тому же файлу одновременно относятся несколько запросов.В этом сценарии несколько потоков могут выполнять операции чтения / записи для одного и того же файла.Теперь отдельные вызовы TransferFrom / TransferTo являются потокобезопасными, согласно документации Java.Но одного вызова этих двух функций может быть недостаточно для полного чтения / записи файла.Если поток A отвечает на запрос загрузки, а поток B отвечает на запрос загрузки, ссылающийся на тот же файл, может случиться так, что:
- Поток A начинает чтение из файла
- В потоке A по какой-то причине вызов чтения возвращается до EOF
- Поток B перезаписывает весь файл одним вызовом записи
- Поток A продолжает чтение из файла
В этом случае загружающий клиент получает часть старой версии и часть новой версии.
Чтобы решить эту проблему, я думаю, что я должен использовать какую-то блокировку, ноЯ не уверен, как это сделать эффективно.Я мог бы создать два синхронизированных метода для чтения и записи, но это, очевидно, вызывает слишком много разногласий.
Лучшее решение, которое я имею в виду, это использовать чередование замков.Перед выполнением любой операции чтения / записи вычисляется хеш на основе имени файла.Затем получается блокировка в позиции lockArr [hash% numOfLocks].Я также считаю, что мне следует использовать ReadWriteLocks, поскольку следует разрешить несколько одновременных чтений.
Теперь это мой анализ проблемы, и я могу ошибаться.Есть ли лучшее решение для этого?