如何确保Java中的多线程只从磁盘加载一次文件

时间:2013-04-26 03:29:22

标签: java multithreading performance

有一个文件可以被多线程以随机顺序访问,如何确保文件只从磁盘加载一次以减少Java中的文件成本?

感谢。

2 个答案:

答案 0 :(得分:4)

我会这样做

private final Map<File, byte[]> cache = new HashMap<File, byte[]>();

public synchronized byte[] readFile(File file) throws IOException {
    byte[] content = cache.get(file);
    if (content == null) {
        content = Files.readAllBytes(file.toPath());
        cache.put(file, content);
    }
    return content;
}

更新

这个版本应该允许异步读取

private final Map<File, byte[]> cache = new HashMap<File, byte[]>();
private final Map<File, Object> locks = new HashMap<File, Object>();

public byte[] readFile(File file) throws IOException {
    Object lock = getLock(file);
    synchronized (lock) {
        byte[] content = cache.get(file);
        if (content == null) {
            content = Files.readAllBytes(file.toPath());
            cache.put(file, content);
        }
        return content;
    }
}

private synchronized Object getLock(File file) {
    Object lock = locks.get(file);
    if (lock == null) {
        lock = new Object();
        locks.put(file, lock);
    }
    return lock;
}

答案 1 :(得分:0)

你可以跟踪你当前正在访问的文件......

public static final long FILE_LOCKED = -1;

private static Set<File> lockedFiles = new HashSet<File>();

private byte[] fileContent;

private synchronized boolean acquireFileLock(File file) {
    if(lockedFiles.contains(file) {
        return false;
    }

    lockedFiles.add(file);
    return true;
}

public long readFile(File file) {
    if(acquireFileLock(file)) {
        // read your File into fileContnent
        lockedFiles.remove(file);
        return bytesRead;
    } else {
        return FILE_LOCKED;
}