我正在实现一个控制器类,它必须对将处理相同类型数据的线程应用锁定。因此,在这种情况下,我已经构建了两个用于apllying和释放锁的类。
现在我在realsing lock时遇到IllegalMonitorStateException异常。 我知道目前我在另一个线程的监视器中。
这是锁定机制:
ConcurrentHashMap<String, Thread> Map = new ConcurrentHashMap<String, Thread>();
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
final Object lock = new Object();
for (Thread thread : threadSet) {
StringBuffer sb = new StringBuffer(thread.getName().toString());
if ((sb.length() == 22) && (sb.toString().matches("[0-9]+"))
&& (thread != Thread.currentThread())) {
utiMap.put(thread.getName().toString(), thread);
}
}
synchronized (lock) {
if (utiMap.containsKey(key)) {
try {
lock.wait();
} catch (InterruptedException e) {
lock.notifyAll();
}
}
}
以下是锁定关系逻辑。
ConcurrentHashMap<String, Thread> Map = new ConcurrentHashMap<String, Thread>();
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Object lock = new Object();
for (Thread thread : threadSet) {
StringBuffer sb = new StringBuffer(thread.getName().toString());
if ((sb.length() == 22) && (sb.toString().matches("[0-9]+"))
&& (thread != Thread.currentThread()) && thread.getState().name().equals("WAITING")) {
utiMap.put(thread.getName().toString(), thread);
System.out.println("I am in controller Release -- ");
thread.resume();
}
}
答案 0 :(得分:4)
你的代码是......我害怕......完全错了。
但更糟糕的是,我怀疑你正在尝试做一些无法做到的事情。或者如果它可以,那么它不应该被完成,因为它不能安全地。
看起来你正试图让一个线程导致另一个线程停止运行...然后恢复。而且你试图在没有受控线程的合作/参与的情况下做到这一点。 (这是我能想到的唯一解释“必须在线程上应用锁定” ...以及你的代码正在执行的旋转。)
不幸的是,你不能在Java中安全地做到这一点。如果您要执行此操作,则需要在线程对象上调用thread.suspend()
以临时停止它,然后在同一线程对象上调用thread.resume()
以使其继续。但很久以前,这两种方法已被弃用,因为(显然)它们容易死锁。
还有其他几点需要注意:
final Object lock = new Object();
...
synchronized(lock) { ....
那段代码错了。 Java原始锁通过在一个(共享)对象上具有多个线程synchronize
来工作。但是您正在同步当前线程可以看到的锁定实例。最终结果是实际上没有同步,也没有锁定。
lock.wait();
这等待notify
lock
个lock
对象的其他线程,但......
lock.notify
对象和建议:
不要尝试暂停/恢复这样的线程。如果你想要一个线程被“控制”,那么修改那个线程以定期检查它是否应该暂停。
你真的,真的需要阅读Java并发,'因为你的尝试解决方案是......坦白地说......垃圾。