在JBoss 6中,Future.get(长超时,TimeUnit单元)不返回

时间:2012-11-09 10:21:02

标签: jboss6.x java.util.concurrent timeoutexception

你好JBoss 6.0 Final中的异步方法调用有问题。

这些类如下所示:

一种是包含许多对象的某种存储。

@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没有Object,因此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块!

更新II

当我用类似于此的方法替换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);
}

任何帮助将不胜感激!

问候

1 个答案:

答案 0 :(得分:0)

没有超时异常,因为永远不会执行t.get。你被困在getAsync的while循环中。你需要立即返回Future,在Future-Implementation中,你需要使用一些countdownlatch来等待结果可用或超时......