Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Servlet上的wait()引发异常_Java_Events_Servlets - Fatal编程技术网

Java Servlet上的wait()引发异常

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

我正在JBossApplicationServer中运行一个web应用程序,并试图从服务器实现一个基于事件的响应

为了实现这一点,我在servlet类上使用了.wait()和.notify()。基本上有一个Ajax请求,servlet用
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)将自身置于此对象的等待集中,然后放弃此对象上的任何和所有同步声明”