Java 将ReentrantLock放入HashMap时,锁丢失
我试图让几个消费者线程听一个生产者线程,直到生产者有东西要发布。我认为可以工作的代码在放入和取出共享类时“丢失”了锁 在控制器类中,我使用 服务器=新服务器() 共享类只是:Java 将ReentrantLock放入HashMap时,锁丢失,java,multithreading,concurrency,Java,Multithreading,Concurrency,我试图让几个消费者线程听一个生产者线程,直到生产者有东西要发布。我认为可以工作的代码在放入和取出共享类时“丢失”了锁 在控制器类中,我使用 服务器=新服务器() 共享类只是: public class MDRequest { protected static ConcurrentHashMap<Long, ReentrantLock> threadLocks = new ConcurrentHashMap<Long, ReentrantLock>(); 从服务
public class MDRequest {
protected static ConcurrentHashMap<Long, ReentrantLock> threadLocks = new ConcurrentHashMap<Long, ReentrantLock>();
从服务器类的输出可以看出,当我从映射中读取锁时,它现在的状态是“Unlocked”。当它被放入时,它的状态为锁定在线程14上
为什么对ReentrantLock的引用会“丢失”锁
有没有一种方法可以在多个使用者线程和服务器线程之间共享锁,从而使锁不会丢失 您面临的问题可能是由于服务器中的以下行造成的
Condition cond = lock.newCondition();
cond.signal();
lock.unlock();
您是否需要从服务器
调用unlock()
,以获得消费者锁定的锁
?我认为调用signal()
就足够了
想想看。问题是
服务器中的线程试图解锁,但没有锁定锁
lock.unlock();
请看清楚的地方:
如果当前线程不是此锁的持有者,则会抛出IllegalMonitorStateException
我并不真正理解您试图解决的问题,但我会认真地看一看java.util.concurrent包中的所有类。特别是ThreadPoolExecutor:。此外,您只能从锁定它的同一线程解锁重入锁。感谢您的解释。您知道有什么方法可以向应该从服务器线程唤醒的使用者线程发送信号吗?您应该将使用者线程使用的条件实例与服务器线程共享,而不要创建新的条件实例。例如,将锁和条件移动到共享类,在服务器类中只需调用cond.signal()。不必使用静态变量在类之间共享对象。您可以在构造函数中传递它们。希望有帮助,(我现在时间有限,对不起)
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
Set<Long> keys = MDRequest.threadLocks.keySet();
Long[] threadIDs = keys.toArray(new Long[1]);
// generates a random series of numbers for each thread and notifies threads about them
while (true) {
Random random = new Random();
int threadRef = random.nextInt(5);
System.out.println("About to signal thread " + threadIDs[threadRef].toString());
// notify the thread of the data
ReentrantLock lock = MDRequest.threadLocks.get(threadIDs[threadRef]);
System.out.println("Thread " + threadIDs[threadRef].toString() + " lock = " + lock.toString());
Condition cond = lock.newCondition();
cond.signal();
lock.unlock();
}
Thread 11 lock = java.util.concurrent.locks.ReentrantLock@272d7a10[Locked by thread Consumer No:0]
Thread 12 lock = java.util.concurrent.locks.ReentrantLock@272d7a10[Locked by thread Consumer No:1]
Thread 13 lock = java.util.concurrent.locks.ReentrantLock@272d7a10[Locked by thread Consumer No:2]
Thread 14 lock = java.util.concurrent.locks.ReentrantLock@272d7a10[Locked by thread Consumer No:3]
Thread 15 lock = java.util.concurrent.locks.ReentrantLock@272d7a10[Locked by thread Consumer No:4]
Thread 16 lock = java.util.concurrent.locks.ReentrantLock@272d7a10[Locked by thread Consumer No:5]
About to signal thread 14
Thread 14 lock = java.util.concurrent.locks.ReentrantLock@272d7a10[Unlocked]
Exception in thread "Price Server" java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signal(AbstractQueuedSynchronizer.java:1885)
at faster.Server.run(Server.java:46)
at java.lang.Thread.run(Thread.java:695)
Condition cond = lock.newCondition();
cond.signal();
lock.unlock();
lock.unlock();