В каких ситуациях доступ к одному файлу становится многопоточным в Java?

«В каких ситуациях доступ к одному файлу становится многопоточным в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Многопоточный доступ к одному файлу возникает, когда несколько потоков приложения пытаются читать или записывать данные в один файл одновременно. Это приводит к состоянию гонки (race condition) и может вызвать:

  • Повреждение данных
  • Непредсказуемое поведение
  • Исключения (например, IOException)

Типичные сценарии:

  1. Веб-приложение с общим лог-файлом

    // Небезопасно: несколько HTTP-запросов пишут в один файл
    public void logToFile(String message) {
    try (FileWriter fw = new FileWriter("app.log", true)) {
        fw.write(message + "n");
    }
    }
  2. Кэширование данных в файл

    // Потоки обновляют общий кэш-файл
    public void updateCache(String key, String value) {
    // Чтение текущего кэша
    // Модификация данных
    // Запись обратно в файл
    }
  3. Конфигурационный файл, обновляемый в runtime

Решение: Используйте синхронизацию или атомарные операции:

// Вариант 1: synchronized
public synchronized void safeWrite(String data) {
    // запись в файл
}

// Вариант 2: Lock
private final ReentrantLock lock = new ReentrantLock();

public void safeWriteWithLock(String data) {
    lock.lock();
    try {
        // запись в файл
    } finally {
        lock.unlock();
    }
}

// Вариант 3: Использование java.nio.channels.FileLock

Лучшая практика: Для логов используйте специализированные библиотеки (Log4j2, Logback), которые уже решают проблему конкурентного доступа.