2013-02-08 61 views
2

我嘗試運行一個異步進程。 基於這個例子:http://tomee.apache.org/examples-trunk/async-methods/README.htmljava @Asynchronous方法:不運行異步

但這種方法時run(Workflow workflow)代碼全部完成addWorkflow(Workflow workflow)只會返回。

然後,當它返回和result.get();叫我去拿例外:

致:java.lang.IllegalStateException:對象不表示acutal未來

任何建議什麼我丟了?

@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); 
} 

回答

4

問題是Java不能修飾隱式的這個指針。

換句話說,@Asynchronous註釋將不會被處理,您正在進行普通的方法調用。

你可以注入你的單身人士並引用自身(稱之爲「self」),然後調用self.addWorkflow。

您可能還想考慮在無狀態bean中運行異步代碼。您正在使用addWorkflow的讀取鎖,但runWorkflow仍然具有寫入鎖定。我認爲你現在有一個死鎖:你直到工作完成才鎖住鎖,但是直到寫鎖被釋放後才能完成工作。

5

所以正常的方法是在調用方法的另一個bean中使用@Asynchronous方法。

@Stateless 
public class ComputationProcessor { 

@Asynchronous 
public Future<Data> performComputation { 
    return new AsyncResult<Data>(null); 
} 
} 

@Stateless 
public class ComputationService { 

@Inject 
private ComputationProcessor mProcessor; 

public void ...() { 
    Future<Data> result = mProcessor.performComputation(); 
    ... 
} 
} 

當你發現,它不會,如果@Asynchronous的方法是在同一個bean不是調用者的工作。