Java Servlet上的wait()引发异常
我正在JBossApplicationServer中运行一个web应用程序,并试图从服务器实现一个基于事件的响应 为了实现这一点,我在servlet类上使用了.wait()和.notify()。基本上有一个Ajax请求,servlet用Java Servlet上的wait()引发异常,java,events,servlets,Java,Events,Servlets,我正在JBossApplicationServer中运行一个web应用程序,并试图从服务器实现一个基于事件的响应 为了实现这一点,我在servlet类上使用了.wait()和.notify()。基本上有一个Ajax请求,servlet用wait阻塞,直到服务器上有一个事件,如果有,就会在servlet上触发notify 问题是,当我在我得到的Servlet上等待(1000*60)时: Servlet.service() for servlet ProcessesServlet threw exc
wait
阻塞,直到服务器上有一个事件,如果有,就会在servlet上触发notify
问题是,当我在我得到的Servlet上等待(1000*60)时:
Servlet.service() for servlet ProcessesServlet threw exception: java.lang.IllegalMonitorStateException
甚至可以对HttpServlet类执行wait()操作吗?在等待对象之前,您必须获得所有权 这通常是通过synchronized语句完成的
synchronized (obj) {
try {
obj.wait(someTime);
} catch (Throwable e) {
e.printStackTrace();
}
}
正如Dystroy所说,你需要在一个对象上有一个锁来调用“wait”。如果出于某种原因,您不能或不想这样做(例如,同时运行的同一方法试图在同一对象上获取锁),您可以使用:
try{
Thread.sleep(time);
} catch (Exception ex){
Thread.interrupted();
}
或者声明一个新对象以获取锁。您不能在servlet中放置wait(…),因为doPost、doGet、。。。是不同步的方法
只能在同步方法或块中放置等待。因此,您可以放置一个同步块并在其中放置wait,如下所示-
synchronized (object) {
try {
object.wait(1000*60);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
被接受的答案缺少一个条件。每当你等待的时候,你应该经常检查一个条件,以保护自己不被虚假唤醒。基本上,等待保证在它所说的所有情况下都能正常返回。它也可以在没有明显原因的情况下返回。你应该遵循这个模式。我不建议在这里或几乎任何地方抓到抛弃者。相反,捕获只是中断异常。此外,还需要确保条件检查是线程安全的。例如,您可以执行以下操作:
private boolean condition;
private Object lock = new Object();
private long timeout = 1000;
public void conditionSatisfied() {
synchronized (lock) {
condition = true;
lock.notify();
}
}
public void awaitCondition() {
synchronized (lock) {
while (!condition) {
try {
lock.wait(timeout);
} catch (InterruptedException e) {
// Probably throw some application specific exception
}
}
// Perform action appropriate to condition
}
}
您会注意到您正在循环等待。超时只是意味着您以高达超时值的间隔等待。如果你想对你的等待时间设定一个总的限制,您应该记录循环外的当前时间,并在每次等待后检查它。在通知之前,我也必须这样做吗?如果我对调用的线程拥有所有权,我就得不到一些东西。使用同步块等待,然后我如何获得将调用的线程的所有权。通知。我的意思是由于等待语句,第一个同步块没有完成…对吗?不会有互斥吗?不完全是:“此方法导致当前线程(称为t)将自身置于此对象的等待集中,然后放弃此对象上的任何和所有同步声明”