3

非同期プロセスを実行しようとしています。この例に基づく:http://tomee.apache.org/examples-trunk/async-methods/README.html

ただし、このメソッドは、入力されたコードが完全に完了addWorkflow(Workflow workflow)した場合にのみ返されます。run(Workflow workflow)

次に、それが戻って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);
}
4

2 に答える 2

7

したがって、通常の方法は、呼び出し元メソッドとは別の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にある場合は機能しません。

于 2014-01-10T07:52:56.880 に答える
4

問題は、Javaが暗黙のthisポインタを装飾できないことです。

つまり、@ Asynchronousアノテーションは処理されず、通常のメソッド呼び出しを実行します。

自分自身への参照を使用してシングルトンを注入し(これを「self」などと呼びます)、次にself.addWorkflowを呼び出すことができます。

ステートレスBeanで非同期コードを実行することを検討することもできます。addWorkflowに読み取りロックを使用していますが、runWorkflowにはまだ書き込みロックがあります。現在、デッドロックが発生していると思います。作業が完了するまでロックを保持していますが、書き込みロックが解除されるまで作業を行うことはできません。

于 2013-02-08T19:35:25.153 に答える