我正在尝试编写一个线程安全结构来保留键值对并在一定时间延迟后自动删除它们。问题是,容器应该通知其他线程删除。
我也尝试notifyAll()
在同步块中使用,但问题仍然存在。
import java.util.Objects;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class Container <K extends Comparable<K>, V> {
private ConcurrentHashMap <K, V> a;
private final int delay = 2;
private final Lock lock = new ReentrantLock();
private final Condition removed = lock.newCondition();
public Container() {
a = new ConcurrentHashMap<>();
}
public synchronized void put(K k, V o) {
lock.lock();
a.put(k, o);
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(delay);
a.remove(k, o);
removed.signalAll();
lock.unlock();
} catch (InterruptedException e){
e.printStackTrace();
}
}).start();
}
public V get(int k) {
return a.get(k);
}
@Override
public String toString() {
return Stream.of(a)
.filter(Objects::nonNull)
.map(Object::toString)
.collect(Collectors.joining(", ", "{", "}"));
}
}
public class Main {
public static void main(String [] args) throws InterruptedException {
Container<Integer, Integer> c = new Container<>();
c.put(0, 10);
System.out.println(c);
c.put(1, 11);
c.put(2, 12);
TimeUnit.SECONDS.sleep(3);
System.out.println(c);
}
}
程序完成代码0
并打印预期值:第一个元素和空结构。但无论哪种方式,我都得到了IllegalMonitorStateException
.
任何想法,谢谢。
我们有几件事要看这里:
lock
removed
这是使用创建的条件 lock
您的主线程lock
在put
方法中获得了锁定。但是它永远不会释放锁;相反,它会创建一个新的Thread
调用removed.signalAll()
. 然而,这个新线程不持有lock
执行此操作所需的锁。
我认为您需要做的是确保每个锁定的线程lock
也解锁它,并且每个调用的线程signalAll
也有一个锁。
public synchronized void put(K k, V o) {
a.put(k, o);
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(delay);
lock.lock(); // get control over lock here
a.remove(k, o);
removed.signalAll();
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句