我有一个多线程
Java应用程序附加到动态生成的路径上的各种文件(大数 – 超过100k).我想防止并发写入.因为这是JVM中的争用,所以我无法使用FileLocks.
相反,我一直在尝试在Path对象上进行如下同步(PathLocker是一个单例).
public class PathLocker {
private final ConcurrentMap pathLockMap = new ConcurrentHashMap<>();
public void lock(Path path) {
pathLockMap.computeIfAbsent(path, p -> new ReentrantLock()).lock();
}
public void unlock(Path path) {
ReentrantLock reentrantLock = pathLockMap.get(path);
if (!reentrantLock.hasQueuedThreads()) { // NPE OCCURS HERE
pathLockMap.remove(path);
}
reentrantLock.unlock();
}
}
唯一的客户端代码如下所示:
Path path = findPath(directory, dataType, bucketEnd, referenceId);
pathLocker.lock(path);
try {
try (FileWriter fileWriter = new FileWriter(path.toFile(), true)) {
fileWriter.write(string);
}
} finally {
pathLocker.unlock(path);
}
但是,当它在PathLocker :: unlock中取消引用reentrantLock时,此代码会相当快速地抛出空指针.
我不明白这个NPE是如何发生的.显然,其他一些线程同时删除了这个值,但是 – 据我所知 – 唯一可能删除锁的线程就是那些排队等待锁定的线程.我错过了什么?