java怎么跨文件,Java-跨多个文件的同步/锁定

In my program, I will be storing each "block" of data in a separate file. Multiple threads will both read from and write to various files, and I want to avoid possible problems from not synchronizing this properly. Essentially, I want a setup where each file behaves as if it has its own ReadWriteLock (Two threads can write to two different files concurrently, but not to the same file). I could do just this (And do some optimizations where ReadWriteLocks are only instantiated when they are needed and destroyed when not), but I'm not sure that this is the "proper" thing to do. Is there a better way to do this?

I've read that using a FileLock would not be the right thing to do in this situation, because it only matters between different processes, and would not do anything in this case because all of my threads are in the same process.

To summarize: What I want to avoid is having one thread reading from one file locking out every other thread from doing anything with the many other files.

解决方案

Here's an example singleton class that provides most of the functionality I think you are describing. It maintains a map of file names to ReadWriteLocks and allows callers to acquire/release a lock based on a file name and a READ/WRITE access type. The class instantiates locks on first use, and hides lock objects from the caller, which should help you to safely clean up locks that are not in use.

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 lockMap = new HashMap();

// 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;

}

}

And here is a simple test scenario to show the LockRegistry in action:

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 testThreads = new ArrayList();

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();

}

}

}

Hope this helps.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值