Подтвердить что ты не робот

Блокировка файлов Java

У меня есть несколько потоков (некоторые из них порождаются Process X, другие - Process Y, et cetera), и каждый поток должен записывать в файл MyFile. Однако, если Thread T1 начинает сначала записывать в MyFile, а затем, когда Thread T2 начинает писать, ему нужно дождаться T1, чтобы освободить файл, чтобы он мог прочитать содержимое, написанное в Thread T1, Другими словами, каждый поток будет иметь метод finalizeThread, например:

private void finalizeThread() {
    File f = new File("MyFile.dat");
    f.createNewFile();  // atomically creates the file, if it doesn't exist
    locked_section {
        readContentsFromFile(f); // read contents if some other thread already modified the file
        modifyContentsFromFile(f); // modify
        writeFile(f); // write, so that new threads can see the content modified by this thread
    }
}

Мой вопрос: как я могу выполнить locked_section в приведенном выше коде? Я изучал класс FileLock, но в Javadoc говорится, что "Блокировки файлов хранятся от имени всей виртуальной машины Java. Они не подходят для управления доступом к файлу несколькими потоками на той же виртуальной машине.".

4b9b3361

Ответ 1

Если файл доступен только из вашей программы, синхронизированный объект блокировки в порядке. Но если вы хотите защитить файл от изменений другими программами во время работы над ним, вы можете использовать функции блокировки файлов Java в java.nio.channels.FileLock (пример). Как говорится в тексте, помните, что в некоторых операционных системах программы все равно могут изменять файлы, если они не проверяют наличие существующей блокировки файлов.

Ответ 2

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

Ответ 3

Вы хотите синхронизировать некоторые объекты. Например:

synchronized(fileLockObject) {
    readContentsFromFile(f);
    modifyContentsFromFile(f);
    writeFile(f);
}