Может ли одна JVM получить две общие блокировки файлов?

#java #multithreading #filelock

#java #многопоточность #блокировка файлов

Вопрос:

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

 File file = new File(lockDir, "tmp.lock");

file.createNewFile();
FileChannel channel = new RandomAccessFile(file, "r").getChannel();
boolean shared = true;
FileLock lock1 = channel.tryLock(0, Long.MAX_VALUE, shared);
assertTrue(lock1.isValid());
assertTrue(lock1.isShared());

// I get an OverlappingFileLockException here:
FileLock lock2 = channel.tryLock(0, Long.MAX_VALUE, shared);
assertTrue(lock2.isValid());
assertTrue(lock2.isShared());

lock1.release();
lock2.release();
 

Но я получаю исключение OverlappingFileLockException в отмеченной строке, даже если я выполняю блокировку в двух разных потоках. Или общая блокировка возможна только для двух разных процессов? Или я неправильно понял общий доступ, и речь идет только о доступе на запись и чтение для частей файла («совместное использование файлового ресурса»)? Я не могу найти документы о том, возможен ли мой вариант использования или нет.

Я хотел бы иметь такое же поведение для блокировки на основе файлов, которое можно получить new ReentrantReadWriteLock() с .readLock() помощью и .writeLock() где разрешено несколько блокировок чтения, но только одна блокировка записи.

Комментарии:

1. На какой платформе вы работаете? Из JavaDocs: «Некоторые платформы не поддерживают общие блокировки, и в этом случае запрос на общую блокировку автоматически преобразуется в запрос на эксклюзивную блокировку».

2. Ubuntu, но я не могу поверить, что он не поддерживает его

3. Действительно, если assertTrue(lock1.isShared()) проходит, то это, вероятно, не проблема.

4. Да, боюсь, я неправильно понял, что означает «поделиться», потому что блокировка разных регионов проходит.

5. Возможно, я также неправильно понимаю, потому что, похоже, ваш вариант использования должен работать: «Блокировка файла является либо эксклюзивной, либо общей. Общая блокировка не позволяет другим одновременно запущенным программам получать перекрывающуюся эксклюзивную блокировку, но позволяет им получать перекрывающиеся общие блокировки. Эксклюзивная блокировка не позволяет другим программам получить перекрывающуюся блокировку любого типа «. Возможно, это проблема, потому что вы пытаетесь заблокировать из того же процесса.

Ответ №1:

из документов java :

tryLock бросает

OverlappingFileLockException — Если блокировка, перекрывающая запрошенную область, уже удерживается этой виртуальной машиной Java, или если другой поток уже заблокирован в этом методе и пытается заблокировать перекрывающуюся область

РЕДАКТИРОВАТЬ: я предполагаю, что условие, выполненное в вашем случае, является перекрывающейся областью, поскольку вы только создаете файл, и он ничего не содержит