【问题标题】:What's wrong with my usage of ReentrantReadWriteLock?我对 ReentrantReadWriteLock 的使用有什么问题?
【发布时间】:2018-04-24 19:49:17
【问题描述】:

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 的使用有什么问题?

【问题讨论】:

    标签: java concurrency readwritelock reentrantreadwritelock


    【解决方案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[]>();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-22
      • 1970-01-01
      • 2018-10-13
      • 2018-11-01
      • 1970-01-01
      相关资源
      最近更新 更多