JavaEE7環境での非同期処理

【前提条件】

[環境]
[参考資料]

Concurrency Utilities for JavaEE 1.0
The Java Community Process(SM) Program - communityprocess - final

[その他]

コンテキストパスは「Sample」、ApplicationPathは「/service」。

並行処理リソースはGlassFishのデフォルトで
組み込まれているものを使用しています。

【概要】

Concurrency Utilities for JavaEEJavaEE上で
非同期処理を実行させるための仕様です。

Concurrency UtilitiesはJavaSE6か提供されていました。
EE環境ではスレッド作成することは許可されていなかったため、
非同期処理は行うことができませんでした。

JavaEE7からはConcurrency Utilities for JavaEE1.0を
使うことにより非同期処理を行うことができるようになりました。

サンプルではJAX-RSのリソースクラスから
非同期で処理を呼び出してみます。

【タスク】

public class FirstAsyncTask implements Runnable{

    @Override
    public void run() {
        System.out.println("First Async Task is start.");
        try {
        System.out.println("First Async Task is waiting.");
            Thread.sleep(5000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        System.out.println("First Async Task is end.");
    }   
}

非同期タスクを実行させるためには
RunnableインターフェイスかCallebleインターフェイスを実装します。

今回は戻り値を返さないのでRunnableインターフェイスを実装しています。

JAX-RS

import javax.annotation.Resource;
import javax.enterprise.concurrent.ManagedExecutorService;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import jp.glory.sample01.task.FirstAsyncTask;

@Path("/sample01")
public class FirstAsyncResource {

    @Resource
    private ManagedExecutorService executeService = null;
    
    @POST
    public Response init() {

        System.out.println("Before execute.");
        executeService.execute(new FirstAsyncTask());
        System.out.println("After execute.");

        return Response.ok("Init it complete").build();
    }
}

javax.enterprise.concurrent.ManagedExecutorServiceクラスのオブジェクトを
インジェクションして、先ほど作成したタスクを実行させています。

ManagedExecutorServiceクラスはResourceアノテーションでインジェクションさせます。

本来であればResourceアノテーションにJNDI名を指定する必要がありますが、
GlassFishのデフォルトを使用しているため、指定をしていません。

ManagedExecutorService#executeメドッドに
先ほど作成したタスクのオブジェクトを渡すと非同期に実行されます。