嗨,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 的对象,因此 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 捕获块被调用!
更新二
当我用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);
}
任何帮助,将不胜感激!
问候