管理多个锁 [英] Managing multiple locks

查看:126
本文介绍了管理多个锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况:我同时处理具有给定键的请求。我可以同时处理任意数量的请求,只要正在进行的每个键都是唯一的。



我是一个在Java中有并发的新秀。这里必须有一些模式/实用程序/现有的问题,但我不知道要搜索什么。



这个类管理锁:

  class LockMap< K> {
private Map< K,Object> locks = new HashMap<>();

void acquireLock(K key)throws InterruptedException {
Object lockObj;
synchronized(locks){
lockObj = locks.get(key);

if(lockObj == null)lockObj = new Object();

locks.put(key,lockObj);
}

synchronized(lockObj){
lockObj.wait();
}
}

void releaseLock(K key){
Object lockObj;
synchronized(locks){
lockObj = locks.get(key);
locks.remove(key);
}

if(lockObj!= null){
synchronized(lockObj){
lockObj.notify();
}
}
}
}

我使用锁管理器这样:

  // lockMap是所有线程共享的LockMap的实例
void doSomething K key){
lockMap.acquireLock(key);
try {
// something
} finally {
lockMap.releaseLock(key);这是正确的方法吗? p>

解决方案

如何:



创建 ConcurrentHashMap< K,Semaphore>



ConcurrentMap< K,Semaphore> doSomething()中的myMap = new ConcurrentHashMap<>();



方法,使用 putIfAbsent()方法添加一个带有一个许可的信号量到地图,只有在地图中不存在键。



然后在键上取一个 get()来获取该键的信号量,然后做你的东西。完成后释放信号量。

  void doSomething(K key){
myMap.putIfAbsent(key,new Semaphore 1));
Semaphore s = myMap.get(myKey);
s.aquire();
try {
// do stuff
} finally {
s.release();
}
}

这个方案唯一的问题是,的键将无限增长,我没有一个良好的无竞争条件的策略,从地图中删除信号量。 (但如果你知道你会重复使用相同的键一遍又一遍,或者列表将增长缓慢,那么也许这是确定。)


I have the following situation: I'm concurrently processing requests that have a given key. I can process any number of requests at the same time, as long as each key in progress is unique.

I am a total rookie with concurrency in Java. There must be some pattern/utility/existing question for this, but I can't figure out what to search for. Hoping somebody could point me in the right direction, or comment on what I have so far.

This class manages the locks:

class LockMap<K> {
    private Map<K, Object> locks = new HashMap<>();

    void acquireLock(K key) throws InterruptedException {
        Object lockObj;
        synchronized (locks) {
            lockObj = locks.get(key);

            if (lockObj == null) lockObj = new Object();

            locks.put(key, lockObj);
        }

        synchronized (lockObj) {
            lockObj.wait();
        }
    }

    void releaseLock(K key) {
        Object lockObj;
        synchronized (locks) {
            lockObj = locks.get(key);
            locks.remove(key);
        }

        if (lockObj != null) {
            synchronized (lockObj) {
                lockObj.notify();
            }
        }
    }
}

Then I use the lock manager like this:

// lockMap is instance of LockMap shared across all threads
void doSomething(K key) {
    lockMap.acquireLock(key);
    try {
        // something
    } finally {
        lockMap.releaseLock(key);
    }
}

Is this the right way to do it?

解决方案

How about this:

create a ConcurrentHashMap<K,Semaphore>

ConcurrentMap<K, Semaphore> myMap = new ConcurrentHashMap<>();

in your doSomething() method, use the putIfAbsent() method to of your map to add a semaphore with one permit to the map, only if the key does not exist in the map.

subsequently do a get() on the key to fetch the semaphore for that key, and then do your stuff. Release the semaphore when done.

void doSomething(K key) {
     myMap.putIfAbsent(key, new Semaphore(1));
     Semaphore s = myMap.get(myKey);
     s.aquire();
     try {
     // do stuff
     } finally {
       s.release();
     }
 }

The only real problem with this scheme is if your list of keys will grow indefinitely, I don't have a good race-condition-free strategy for removing the semaphore from the map. (But if you know you will reuse the same keys over and over, or the list will grow slowly, then maybe this is ok.)

这篇关于管理多个锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆