2012-06-08 8 views
6

私はJbossアプリケーションサーバーでWebアプリケーションを実行していますが、サーバーからのイベントベース応答を実装しようとしています。サーブレットでwait()が例外をスローする

これを実現するには、サーブレットクラスで.wait()と.notify()を使用しています。基本的には、Ajaxリクエストがあり、サーバー上にイベントが発生するまでサーブレットはwaitでブロックされ、サーブレットでnotifyが発生するまで、サーブレットはブロックされます。

Servlet.service() for servlet ProcessesServlet threw exception: java.lang.IllegalMonitorStateException 

が、HttpServletのクラスのwait()を行うことも可能です:私は私が手にサーブレットに(* 60 1000)を待つないとき

問題がありますか?

答えて

7

オブジェクトを待つ前に、所有権を取得する必要があります。

これは通常、synchronized文で行われます。

synchronized (obj) { 
     try { 
      obj.wait(someTime); 
     } catch (Throwable e) { 
      e.printStackTrace(); 
     } 
    } 
+0

通知する前に同じことをする必要がありますか? –

+0

[はい](http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#notify()) –

+0

私は得ることができないsomehtingが...もし私が同期ブロックを使用して.waitを呼び出すスレッドの所有権を取得する方法.notifyを呼び出すスレッドの所有権を取得する方法を教えてください。私は最初の同期ブロックは、待機ステートメントのために完了していないことを意味...正しい?相互排除はありませんか? –

1

Dystroy氏によると、オブジェクトをロックして「待機」する必要があります。

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

をしたり、新しいオブジェクトを宣言します、何らかの理由で、あなたがまたはしたくないことができない場合(たとえば、同じオブジェクトのロックを取得しようとして同時に実行されているのと同じ方法のように)、あなたは使用することができますその上に錠を得る。

2

doPost、doGet、...は同期メソッドではないため、サーブレットにwait(...)を入れることはできません。

同期メソッドまたはブロックでのみ待機できます。同期ブロックを入れて待機させることができます。下に -

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

受け入れられた回答に条件がありません。あなたが待っているときはいつも、偽の起床から身を守るための状態をチェックするべきです。基本的に、待っていることは、それがそうするすべてのケースで正常に戻ることです。それは明白な理由がなくても戻ることができます。 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 
    } 
} 

あなたはループで待っていることに気づくでしょう。タイムアウトは、タイムアウト値までの間隔で待機することを意味します。待機時間に全体的な制限を設定する場合は、ループの外にある現在の時間をメモし、待機するたびに確認してください。

関連する問題