你好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);
}
任何帮助将不胜感激!
问候
答案 0 :(得分:0)
没有超时异常,因为永远不会执行t.get
。你被困在getAsync
的while循环中。你需要立即返回Future,在Future-Implementation中,你需要使用一些countdownlatch来等待结果可用或超时......