Почему одна JVM дважды получает FileLock, вызывает исключение OverlappingFileLockException? - PullRequest
0 голосов
/ 16 марта 2011

Почему дважды получить FileLock в одной JVM вызовет исключение OverlappingFileLockException? Почему второй замок блокировки не может быть заблокирован и получить блокировку, когда он выпущен?

Ответы [ 4 ]

2 голосов
/ 16 августа 2013

И блокирующий метод lock (), и неблокирующий метод trylock () будут генерировать OverlappingFileLockException "Если блокировка, которая перекрывает запрошенный регион, уже удерживается этой виртуальной машиной Java, или если другой поток уже заблокирован в этом методе и является пытаясь заблокировать перекрывающуюся область того же файла ", как описано в FileChannel javadoc .

Причина - предотвращение тупиковых ситуаций. Если другой поток уже заблокирован при попытке получить эту блокировку, и вы должны были получить эту блокировку, вы можете затем попытаться получить некоторую блокировку, которую удерживает этот другой поток, что приведет к взаимоблокировке в JVM. И если блокировка, которую вы пытались получить, уже удержана, вы, возможно, уже держите другую блокировку, которую пытается получить другая нить, которая уже удерживает эту блокировку, снова приводя к взаимоблокировке - поэтому выдается исключение, чтобы вы знали вашей потенциальной ошибки кодирования. Если это произойдет при вызове tryLock (), вы не будете заблокированы, поэтому не будете иметь тупиковой ситуации, но, скорее всего, попадете в бесконечный цикл попыток получить блокировку. Вы должны получать блокировки всегда в одном и том же порядке, тогда не будет шансов на тупик, и вы не столкнетесь с этим, потому что ни один поток, пытающийся получить эту блокировку, не будет заблокирован.

Это означает, что вы не должны последовательно выполнять lock (), tryLock () для одной и той же блокировки. Если вы уже получили блокировку, вы должны помнить об этом и не должны запрашивать ее снова.

Обратите внимание, что если какая-то другая программа уже удерживает эту блокировку, исключение не будет выдано, и tryLock () просто вернет null, тогда как lock () будет блокировать, пока не сможет получить блокировку (т.е. другая программа разблокировала область файла).

И нет, это не означает, что tryLock () не является поточно-ориентированным. Но это подразумевает, что вам может понадобиться перехватить и обработать OverlappingFilelLockException в вашем коде, даже если это не объявленное исключение.

0 голосов
/ 16 марта 2011

Фактически, это метод, который вы вызываете для получения FileLock, который определяет, блокируется поток или нет:

  • FileChannel.lock(...) будет блокироваться до тех пор, пока не будет получена блокировка.
  • FileChannel.tryLock(...) немедленно вернется, если блокировка не может быть получена.

Все это четко задокументировано в FileChannel javadoc .

Между прочим, заявленная причина @ glowcoder не верна ... "N" в NIO означает Новый, а не Неблокирующий. Конечно, NIO поддерживает блокирующий и неблокирующий ввод / вывод. (ОК, может быть, это была просто шутка ... :-))

0 голосов
/ 29 марта 2012

Я сталкиваюсь с той же проблемой, это подразумевает, что FileChannel.Lock / TryLock не безопасен для потоков.И вы должны иметь синхронизацию через блокировку FileChannel в той же JVM.Ограничение ReentranetLock или SingleThread.

0 голосов
/ 16 марта 2011

Возможно, потому что он находится в пакете NON BLOCKING IO? : -)

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

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