У меня проблема с ReentrantReadWriteLock
.Поток зависает, когда я пытаюсь стереть файл.У меня есть запланированная операция чтения и возможная операция записи (когда пользователь нажимает кнопку), которые используют один экземпляр ReentrantReadWriteLock
.Следующий код выглядит непригодным для использования, извините, я упростил все в одном месте.
public class FileDB {
private static final String ORDERS_FILENAME = "orders.tsv";
private ReadWriteLock ordersLock;
private FileDB1() {
ordersLock = new ReentrantReadWriteLock();
// Swing Timer
ordersTimer = new Timer(0, (ActionEvent e) -> {
readFileSplittedByTab("orders.tsv", 5, ordersLock);
});
ordersTimer.setDelay(5 * 1000); // 5 sec
ordersTimer.start();
}
private List<String[]> readFileSplittedByTab(String filePath,
int columns, ReadWriteLock lock) {
lock.readLock().lock();
File file = new File(filePath);
// if file is absent or empty return empty list
if (!file.exists() || file.length() == 0)
return new ArrayList<String[]>();
List<String> lines = null;
try {
lines = Files.readAllLines(Paths.get(file.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
} finally {
lock.readLock().unlock();
}
List<String[]> splittedFile = new ArrayList<>();
String[] parts = null;
for (String line : lines) {
parts = line.split("\t");
if (parts.length != columns) // skip bad string
continue;
splittedFile.add(parts);
}
return splittedFile;
}
private void wipeFile(String filePath, ReadWriteLock lock) {
PrintWriter printWriter = null;
try {
lock.writeLock().lock();
Files.newBufferedWriter(Paths.get(filePath), StandardOpenOption.TRUNCATE_EXISTING).close();
} catch (IOException e) {
e.printStackTrace();
} finally {
lock.writeLock().unlock();
}
}
}
И операция записи выглядит так:
wipeFile(ORDERS_FILENAME, ordersLock);
Когда метод wipeFile()
срабатывает дляпервый раз все работает.Но начиная со второй попытки зависает на lock.writeLock().lock()
;Я пытался вызвать метод wipeFile()
из другого потока, потому что ребята писали, что блокировка записи не должна использоваться в одном потоке с блокировкой чтения.
Executors.newSingleThreadExecutor().execute(() -> {
wipeFile(ORDERS_FILENAME, ordersLock);
});
Но это не помогает, другой поток тоже зависает.
Итак, вопрос в том, что не так с моим использованием ReentrantReadWriteLock?