2

JBoss 6.0 Final の非同期メソッド呼び出しに問題があります。

クラスは次のようになります。

1 つは、多数のオブジェクトを含むある種のストレージです。

@Singleton
public class Storage {

    private Map<Integer, Object> storage = new HashMap<Integer, Object>();

    @Asynchronous
    public Future<Object> getAsync(int id) {
        Object obj = null;
        while (null == obj ) {
          obj = storage .remove(id);
        }
        return new AsyncResult<Object>(obj);
    }

    public void add(int id, Object obj) {
        storage.put(id, obj(    
    }
}

次に、何かを処理し、指定された ID を持つストレージからオブジェクトを見つけようとするクラスがあります。ストレージからこの ID のオブジェクトが見つかるまで、指定された時間待機する必要があります。何もない場合は、検索を停止して続行します。

@Singleton
public class Executor {

    @Inject
    private Storage storage;

    public void execute(int id) {

        Future<Object> fut = storage.getAsync(id);
        Object obj; 
        try {
            obj = t.get(30L, TimeUnit.SECONDS);
                    // go on processing of obj is found
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            //no object can be found.
            // but we never reach this place
        }
    }
}

指定された ID のオブジェクトがストレージに存在しない可能性があるため、getAsync() メソッドのループは「無限」になります。そのため、30 秒後に TimeoutException をスローする必要があります。興味深いのは、TimeoutException がスローされないことです。

非同期メソッドで「無限」ループを作成しないなどのポイントがありませんか?

アップデート:

スタンドアロン アプリケーションで同様のことを行うと、適切に動作します。

public class Test {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        Callable<Object> task = new Callable<Object>() {
          public Object call() {
              int i = 0;
              while(i == 0) {
                  i = 0;
              }
               return null;
          }
        };
        Future<Object> future = executor.submit(task);
        try {
          Object result = future.get(5, TimeUnit.SECONDS);
        } catch (TimeoutException ex) {
            ex.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

スタンドアロンでは TimeoutException catch ブロックが呼び出されるため、基本的に非同期メソッドで無限ループを実行しても問題ありません。

アップデートⅡ

getAsync()メソッドをこれに似たものに置き換えるとget()、TimeoutException をスローせずに正常に戻ります。しかし、それは私が期待することです!

@Asynchronous
public Future<Telegram> getTelegramAsync(int telegramId) {
    Telegram tlgrm = null;
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return new AsyncResult<Telegram>(tlgrm);
}

どんな助けでも大歓迎です!

よろしく

4

1 に答える 1