Что не так с моим использованием ReentrantReadWriteLock?

У меня проблема с ReentrantReadWriteLock. Тема зависает, когда я пытаюсь стереть файл. У меня есть запланированная операция чтения и возможная операция записи (когда пользователь нажимает кнопку), в которых используется один экземпляр ReentrantReadWriteLock. Следующий код выглядит непригодным для использования, извините, для простоты я собрал все в одном месте.

public class FileDB {
    private static final String ORDERS_FILENAME = "orders.tsv";

    private ReadWriteLock ordersLock;

    private FileDB() {
        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?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
125
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Неправильно то, что вы никогда не снимаете блокировку чтения после того, как файл был стерт (удален или длина файла равна 0):

    lock.readLock().lock();

    File file = new File(filePath);

    // if file is absent or empty return empty list
    if (!file.exists() || file.length() == 0) {
        // lock.readLock().unlock(); // this line is missing
        return new ArrayList<String[]>();
    }

Другие вопросы по теме