簡體   English   中英

Servlet上的wait()拋出異常

[英]wait() on Servlet throws Exception

我在Jboss應用服務器上運行一個Web應用程序,我正在嘗試從服務器實現事件庫響應。

為了實現這一點,我在servlets類上使用了.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();
        }
    }

你不能把wait(...)放在servlet中因為doPost,doGet,...不是同步方法。

你可以只在同步方法或塊中等待。 所以你可以放一個同步塊並放入等待。如下所示 -

    synchronized (object) {
        try {
            object.wait(1000*60);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

接受的答案是缺少一個條件。 每當你等待時,你應該總是檢查一個條件,以保護自己免受虛假的喚醒。 基本上,等待保證在所說的所有情況下都會正常返回。 它也可以沒有明顯的原因返回。 你應該遵循Javadoc的模式。 我不建議在這里或幾乎任何地方捕捉Throwable。 相反,只捕獲InterruptedException。 此外,您需要確保條件檢查是線程安全的。 因此,例如,您可以執行以下操作:

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
    }
}

你會注意到你正在等待一個循環。 超時僅表示您以超時值的間隔等待。 如果要對等待時間進行總體限制,則應記下循環外的當前時間,並在每次等待后進行檢查。

正如Dystroy所說,你需要鎖定一個對象來對其進行“等待”。 如果由於某種原因,您不能或不想這樣做(例如同時運行同一個方法試圖鎖定同一個對象),您可以使用:

try{
    Thread.sleep(time);
} catch (Exception ex){
    Thread.interrupted();
}

或者聲明一個獲取鎖定的新對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM