Условие, которое вы хотите избежать, обычно называется race condition
, а то, чего вы хотите избежать, - это метод синхронизации между потоками. Доступно больше вариантов, но наиболее подходящими для вашего случая являются mutex
и read-write lock
.
A mutex
в основном просто блокирует ресурс перед выполнением любой операции с общим ресурсом, независимо от типа операции, и освобождает его после завершения операции. Таким образом, read
заблокирует ресурс и любые другие операции, read
или write
будут заблокированы.
write
также заблокирует ресурс, поэтому снова никакие другие операции read
или write
не могут быть выполнены до того, как действие будет прекращено и mutex
разблокировано. Таким образом, у mutex
есть 2 состояния: заблокировано и разблокировано.
read-write lock
дает вам больше свободы благодаря тому факту, что операции только для чтения не приводят к несоответствиям. A read-write lock
имеет 3 состояния: разблокировано, блокировка чтения, блокировка записи. Блокировка записи работает как обычный мьютекс, блокирующий любую другую операцию. Блокировка чтения наоборот блокирует только операции записи.
Я не эксперт по Java, но с этот ответ mutex
в Java можно использовать следующим образом:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
private final Lock lock = new ReentrantLock(true);
lock.lock()
/*open file and do stuff*/
try {
// do something
} catch (Exception e) {
// handle the exception
} finally {
lock.unlock();
}
Вместо здесь вы можете найти описание класса блокировки чтения-записи.
С точки зрения реализации вы можете создать экземпляр одного из двух методов синхронизации, и ваши экземпляры потока чтения / записи сохранят ссылку на него как переменную экземпляра.