gpt4 book ai didi

Java-跨多个文件的同步/锁定

转载 作者:行者123 更新时间:2023-12-02 05:38:12 27 4
gpt4 key购买 nike

在我的程序中,我将把每个“ block ”数据存储在一个单独的文件中。多个线程都会读取和写入各种文件,我想避免因未正确同步而可能出现的问题。本质上,我想要一个设置,其中每个文件的行为就好像它有自己的 ReadWriteLock 一样(两个线程可以同时写入两个不同的文件,但不能写入同一个文件)。我可以这样做(并进行一些优化,其中仅在需要时实例化 ReadWriteLock 并在不需要时销毁),但我不确定这是“正确”的做法。有更好的方法吗?

我读到,在这种情况下使用FileLock不是是正确的做法,因为它只在不同进程之间起作用,并且不会做任何事情在这种情况下,因为我的所有线程都在同一个进程中。

总结一下:我想要避免的是让一个线程从一个文件读取数据,从而锁定其他所有线程,使其无法对许多其他文件执行任何操作。

最佳答案

这是一个示例单例类,它提供了我认为您正在描述的大部分功能。它维护文件名到 ReadWriteLocks 的映射,并允许调用者根据文件名和读/写访问类型获取/释放锁。该类在第一次使用时实例化锁,并向调用者隐藏锁对象,这应该可以帮助您安全地清理未使用的锁。

public enum LockRegistry {

// make our class a singleton
INSTANCE;

// map of file names to locks - You may want to change the keys to be File or
// something else, just be wary of the class's hashCode() semantics
private Map<String, ReadWriteLock> lockMap = new HashMap<String, ReadWriteLock>();

// lock to protect our registry - helps to prevent multiple threads
// from instantiating a lock with the same key
private Lock registryLock = new ReentrantLock();

// allow callers to specify the lock type they require
public enum LockType {
READ, WRITE
}

public void acquire(String fileName, LockType type) {

// lazily instantiates locks on first use
ReadWriteLock lock = retrieveLock(fileName);

switch (type) {
case READ:
lock.readLock().lock();
break;
case WRITE:
lock.writeLock().lock();
break;
default:
// handle error scenario
break;
}

}

public void release(String fileName, LockType type) {

ReadWriteLock lock = retrieveLock(fileName);

switch (type) {

case READ:
lock.readLock().unlock();
break;
case WRITE:
lock.writeLock().unlock();
break;
default:
// handle error scenario
break;
}

}

private ReadWriteLock retrieveLock(String fileName) {

ReadWriteLock newLock = null;

try {

registryLock.lock();

newLock = lockMap.get(fileName);

// create lock and add to map if it doesn't exist
if (newLock == null) {
newLock = new ReentrantReadWriteLock();
lockMap.put(fileName, newLock);
}
} finally {

registryLock.unlock();
}

return newLock;
}

}

这是一个简单的测试场景,用于显示 LockRegistry 的实际操作:

public class LockTester implements Runnable {

private int id;
private String fileName;
private LockType type;

public LockTester(int id, String fileName, LockType type) {

this.id = id;
this.fileName = fileName;
this.type = type;
}

@Override
public void run() {
try {
System.out.println("Consumer" + id + " acquiring " + type + " for "
+ fileName);
LockRegistry.INSTANCE.acquire(fileName, type);

System.out.println("Consumer" + id + " holding " + type + " for "
+ fileName);

// hold the lock for 2 seconds
Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();
} finally {

LockRegistry.INSTANCE.release(fileName, type);

System.out.println("Consumer" + id + " release " + type + " for "
+ fileName);
}
}

public static void main(String[] args) {

List<Thread> testThreads = new ArrayList<Thread>();

testThreads.add(new Thread(new LockTester(1, "file1", LockType.READ)));
testThreads.add(new Thread(new LockTester(2, "file1", LockType.READ)));
testThreads.add(new Thread(new LockTester(3, "file1", LockType.WRITE)));
testThreads.add(new Thread(new LockTester(4, "file1", LockType.WRITE)));
testThreads.add(new Thread(new LockTester(5, "file2", LockType.WRITE)));
testThreads.add(new Thread(new LockTester(6, "file3", LockType.WRITE)));
testThreads.add(new Thread(new LockTester(7, "file4", LockType.WRITE)));

for (Thread t : testThreads) {
t.start();
}

}

}

希望这有帮助。

关于Java-跨多个文件的同步/锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24771092/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com