gpt4 book ai didi

Java:作用于同一元素的锁定函数

转载 作者:行者123 更新时间:2023-12-02 00:09:16 25 4
gpt4 key购买 nike

有许多线程处理同一个 map 上的元素,每个线程都有一个代码,例如:

THREAD_1 works on an element with code "1234"
THREAD_2 works on an element with code "1234"
THREAD_3 works on an element with code "9876"
etc...

元素不是永久的,即 THREAD_1 可能会删除元素“1234”,然后再次插入。我想要的是,当 THREAD_1 正在处理元素“1234”(也将其删除)时,THREAD_2 必须等待。

有办法吗?

一个可能的解决方案可能是在 HashMap 中插入一个假元素,然后使用该元素上的“synchronized”子句强制同步。你有什么想法? (显然,如果线程删除带有关联代码的元素,假元素也会保留在 map 中)...

最佳答案

鉴于您的特定问题,没有一个 java 标准对象可以解决您的所有问题。我认为这是一个正确的解决方案,并且不会在锁定映射中保留任何不必要的键或值:

// we don't use a ConcurrentHashMap, because we have some other operations 
// that need to be performed in atomically with map.put and map.remove.
// ConcurrentHashMap would of course also work, but it doesn't remove the
// need for external synchronization in in our case.
Map<String, CountingLock> locksMap = new HashMap<String, CountingLock>();
...

HttpResponse myFunction(String key) {

CountingLock lock;
synchronized(locksMap){
lock = locksMap.get(key);
if(lock == null){
lock = new CountingLock();
locksMap.put(key, lock);
}
lock.prepare(); // has to be done while holding the lock of locksMap.
// basically tells other threads that the current
// thread intends to acquire the lock soon. This way,
// the other threads know not to remove this lock
// from locksMap as long as another one has indicated
// that he is going to need it soon.
}

lock.lock(); // has to be done while NOT holding the lock of locksMap,
// or we risk deadlock situations.

try {
// ...
// work
// ...
} finally {
synchronized(locksMap) {
if(lock.unlock() == 0){
// no other thread is intending to use this lock any more.
// It is safe to remove it from the map. The next thread
// will just have to recreate a new lock for the same key.
locksMap.remove(key);
}
}
}

return SOMETHING;
}

private static class CountingLock {
// The number of threads that are trying to access the protected Key
private AtomicInteger interestedThreads = new AtomicInteger(0);

private Lock lock = new ReentrantLock();

public void prepare(){
interestedThreads.incrementAndGet();
}

public void lock(){
lock.lock();
}

public int unlock(){
lock.unlock();
return interestedThreads.decrementAndGet();
}
}

此代码在所有情况下都应按预期工作。这是一个需要解决的有趣问题:-)

关于Java:作用于同一元素的锁定函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13201210/

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