2016-04-13 10 views
8

タスクを実行するスレッドを作成しようとしていて、特定の時間(たとえば100秒)内に終了しない場合は例外をスローします。現在私は、タスクをrunnableオブジェクトにカプセル化し、ExecutorServiceFutureクラスを使用してタイムアウトを実行することで、これを実行しようとしています。私は自分のWebサービスを起動したときしかし、私はこの例外を取得:Spring Webサーバでタイムアウトを指定してタスクを実行するためのスレッドを作成する

java.util.concurrent.ExecutionException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.localhostInterpolatorHealthCheck': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request. 
at java.util.concurrent.FutureTask.report(FutureTask.java:122) 
at java.util.concurrent.FutureTask.get(FutureTask.java:202) 

私はそれはあなた自身のスレッドを定義し、春にスレッドを始めるためにそれらを起動するのと同じくらい簡単ではないことをオンラインで読むので、私は行う方法を疑問に思ってこの?私は何が欠けていますか?

+1

例外メッセージによると、スケジュールされたスレッドの実行がリクエストスコープ内にない間に、リクエストスコープのSpring Beanを使用しています。 – AdamSkywalker

+0

@AdamSkywalker実行可能ファイルを拡張し、そのクラスをスレッド内にカプセル化し、 'Future'と' ExecutorService'を使って時間制限付きのコードブロックを行うクラスを作成しています。コードブロックは、一連の正常性テストを実行します。新しいクラスはそれをサポートするBeanを持っていません(私はそれが必要とは思わなかった)、これはおそらくどこが間違っているのでしょうか? –

+0

私は十分な情報を持っていない、私はそのコードが何とか豆を使用して参照してください。あなたは完全なスタックトレースを持っていますか?これで、例外の先頭だけが表示されます。 – AdamSkywalker

答えて

3

はこれを試してみてください:

/** 
    * Executes a task with a specified timeout. 
    */ 
    public final class TimeoutController { 

     /** 
     * Do not instantiate objects of this class. Methods are static. 
     */ 
     private TimeoutController() { 
     } 

     /** 
     * Executes <code>task</code>. Waits for <code>timeout</code> 
     * milliseconds for the task to end and returns. If the task does not return 
     * in time, the thread is interrupted and an Exception is thrown. 
     * The caller should override the Thread.interrupt() method to something that 
     * quickly makes the thread die or use Thread.isInterrupted(). 
     * @param task The thread to execute 
     * @param timeout The timeout in milliseconds. 0 means to wait forever. 
     * @throws TimeoutException if the timeout passes and the thread does not return. 
     */ 
     public static void execute(Thread task, long timeout) throws TimeoutException { 
      task.start(); 
      try { 
       task.join(timeout); 
      } catch (InterruptedException e) { 
       /* if somebody interrupts us he knows what he is doing */ 
      } 
      if (task.isAlive()) { 
       task.interrupt(); 
       throw new TimeoutException(); 
      } 
     } 

     /** 
     * Executes <code>task</code> in a new deamon Thread and waits for the timeout. 
     * @param task The task to execute 
     * @param timeout The timeout in milliseconds. 0 means to wait forever. 
     * @throws TimeoutException if the timeout passes and the thread does not return. 
     */ 
     public static void execute(Runnable task, long timeout) throws TimeoutException { 
      Thread t = new Thread(task, "Timeout guard"); 
      t.setDaemon(true); 
      execute(t, timeout); 
     } 

     /** 
     * Signals that the task timed out. 
     */ 
     public static class TimeoutException extends Exception { 
      /** Create an instance */ 
      public TimeoutException() { 
      } 
     } 
    } 
+0

同じエラー:スレッド "Thread-25"の例外org.springframework.beans.factory.BeanCreationException: 'scopedTarget.localhostInterpolatorHealthCheck'という名前のBeanを作成中にエラーが発生しました:スコープ 'request'が現在のスレッドでアクティブではありません。あなたがシングルトンからそれを参照するつもりならば、このBeanのスコープ付きプロキシを定義することを検討してください。ネストされた例外はjava.lang.IllegalStateExceptionです。原因:java.lang.IllegalStateException:スレッドバインド要求が見つかりませんでした。 –

+0

beanがscopedTarget.localhostInterpolatorHealthCheck Beanを正しく定義していないため、スレッドはこのBeanから要求を取得できません。 – Ahmad

+0

あなたの春の設定であなたのbeanを適切に定義すればうまく動作します。 – Ahmad

1

あなたが代わりにいくつかの@asyncメソッドを持って、そして、あなたのメインのコードフローからそれらを実行して、先物のリストを取得することができます。タイムアウトが経過すると、結果を得るか、実行を停止することができます(キャンセル/終了)。

これは、あなたがスプリングマネージドBeanを呼び出すときに利点があります。したがって、すべての依存関係注入プロパティが利用可能になります。しかし、あなたが提出するジョブ/スレッドの量に注意する必要があります。

@asyncアノテーションを使用するには、xml構成の特定の行またはBeanのAsyncEnabledアノテーションを使用して非同期の処理を有効にする必要があります。

関連する問題