我尝试运行一个异步进程。基于以下示例:http : //tomee.apache.org/examples-trunk/async- methods/README.html
但是,addWorkflow(Workflow workflow)只有在run(Workflow workflow)完全完成其中的代码后,该方法才会返回。
addWorkflow(Workflow workflow)
run(Workflow workflow)
然后当它返回并被result.get();调用时,我将得到异常:
result.get();
原因:java.lang.IllegalStateException:对象不代表实际的Future
有什么建议我想念的吗?
@Singleton public class WorkflowProcessor { @EJB private WorkflowManager workflowManager; private final static Logger log = Logger.getLogger(WorkflowProcessor.class.getName()); public void runWorkflows(Collection<Workflow> workflows) throws Exception{ final long start = System.nanoTime(); final long numberOfWorkflows = workflows.size(); Collection<Future<Workflow>> asyncWorkflows = new ArrayList<>(); for(Workflow workflow : workflows){ Future<Workflow> w = addWorkflow(workflow); asyncWorkflows.add(w); } log.log(Level.INFO, "workflow jobs added {0}", new Object[]{numberOfWorkflows}); for(Future<Workflow> result : asyncWorkflows){ result.get(); } final long total = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); log.log(Level.INFO, "WorkflowProcessor->runWorkflows {0} workflows completed in:{1}", new Object[]{numberOfWorkflows, total}); } @Asynchronous @Lock(LockType.READ) @AccessTimeout(-1) private Future<Workflow> addWorkflow(Workflow workflow){ run(workflow); return new AsyncResult<Workflow>(workflow); } private void run(Workflow workflow){ this.workflowManager.runWorkflow(workflow); }
问题是Java无法装饰隐式this指针。
换句话说,将不会处理@Asynchronous批注,而您正在执行普通的方法调用。
您可以为自己的单例添加对自身的引用(称为“ self”),然后调用self.addWorkflow。
您可能还需要考虑在无状态Bean中运行异步代码。您正在为addWorkflow使用读锁,但是runWorkflow仍然具有写锁。我认为您现在有一个死锁:您要持有该锁,直到工作完成为止,但是直到释放写锁后才能进行任何工作。