陷阱错误使用 wait() notify()
方法 object.wait(),object.notify() 和 object.notifyAll() 旨在以非常特定的方式使用。 (参见 http://stackoverflow.com/documentation/java/5409/wait-notify#t=20160811161648303307 )
失去通知问题
一个常见的初学者错误是无条件地称之为 object.wait()
private final Object lock = new Object();
public void myConsumer() {
synchronized (lock) {
lock.wait(); // DON'T DO THIS!!
}
doSomething();
}
这是错误的原因是它依赖于其他一些线程来调用 lock.notify() 或 lock.notifyAll(),但没有什么能保证其他线程在消费者线程叫做 lock.wait() 之前没有进行该调用。
如果某个其他线程尚未等待通知,lock.notify() 和 lock.notifyAll() 根本不做任何事情。在此示例中调用 myConsumer() 的线程将永远挂起,如果为时太晚而无法捕获通知。
非法监控状态错误
如果你在一个对象上调用 wait() 或 notify() 而不持有锁,那么 JVM 将抛出 IllegalMonitorStateException。
public void myConsumer() {
lock.wait(); // throws exception
consume();
}
public void myProducer() {
produce();
lock.notify(); // throws exception
}
(wait() / notify() 的设计要求锁定,因为这是避免系统竞争条件所必需的。如果可以在没有锁定的情况下调用 wait() 或 notify(),那么就不可能实现这些原语的主要用例:等待条件发生。)
等待/通知太低级别
避免 wait() 和 notify() 问题的最好方法是不使用它们。通过使用 java.utils.concurrent 包中提供的更高级别的同步对象(队列,障碍,信号量等),可以解决大多数同步问题。