Рассмотрим следующий код:
private static final Object LOCK = new Object();
private static final ExecutorService executorService = Executors.newFixedThreadPool(10); // Also used for a few other tasks.
public static void save(Object o) {
String s = serialize(o);
executorService.submit(() -> {
// Do we have a race condition here?
synchronized (LOCK) {
saveToFile(s, new File("test.txt")); // overwrites the file
}
});
}
public static void main(String[] args) {
save(args[0]);
save(args[1]);
}
save(Object o)
вызывается только в основном потоке. Я знаю, что пул потоков обрабатывает отправленные задачи из внутренней очереди по порядку, но может ли это случиться теоретически, что существует состояние гонки до достижения synchronized (LOCK)
, а вывод файла - args[0]
?
Если да, то как этого избежать? Я знаю, что однопоточный исполнитель определенно решит эту проблему, но я хочу по возможности использовать этот пул потоков.
Edit: Я думаю, что один из возможных способов - использовать Queue
:
private static final Queue<String> queue = new ConcurrentLinkedQueue<>();
public static void save(Object o) {
queue.add(serialize(o));
executorService.submit(() -> {
synchronized (LOCK) {
saveToFile(queue.remove(), new File("test.txt"));
}
});
}