web-dev-qa-db-ja.com

Java EE仕様とマルチスレッド

私はJava StrutsとSpringを使用するEEアプリケーションを作成しています。操作の1つで、データベース処理が重いため、パフォーマンスの問題があります。ここでマルチスレッドを使用できるかどうかを知りたいですか?I Java EE仕様では、サーバーによって作成されたものとは別にカスタムスレッドを作成することは許可されていません(私はWeblogicを使用しています)。これについて教えてください。

28
Sid

この質問はときどき出てきます。

仕様に従って、それは許可されていません。確認するのに最適なページは次のとおりです。 Q/A:J2EE制限

そうは言っても、特にWeblogicでWorkManagerを使用してスレッドを生成する方法はいくつかあります。

次の質問をご覧ください。

最初の1つがEJBを対象としているという事実はそれほど重要ではないはずであり、ファイルシステムへのアクセスに関する最後の1つは一般的な制限に関するものです。

それが役に立てば幸い。

7
ewernli

Java EE環境でスレッドを作成するための推奨される方法は、EE7仕様の一部であるConcurrency Utils APIを使用することです。

このAPIを使用することにより、新しいスレッドが作成され、コンテナーによって管理されます。これにより、すべてのEEサービスがスレッドで利用できることが保証されます(セキュリティ、トランザクションなど)。

以下の例は、自分のサイト here および here から取得したものです

ManagedExecutorServiceの使用

ManagedExecutorServiceを使用して新しいスレッドを作成するには、最初にCallableを実装するタスクオブジェクトを作成します。 call()メソッド内で、別のスレッドで実行する作業を定義します。

public class ReportTask implements Callable<Report> {

    Logger logger = Logger.getLogger(getClass().getSimpleName());

    public Report call() {
        try {
            Thread.sleep(3000);
        catch (InterruptedException e) {
            logger.log(Level.SEVERE, "Thread interrupted", e);
        }
        return new Report();
    }
}

次に、ManagedExecutorServiceのsubmit()メソッドに渡して、タスクを呼び出す必要があります。

@Stateless
public class ReportBean {

    @Resource
    private ManagedExecutorService executorService;

    public void runReports() {
        ReportTask reportTask = new ReportTask();
        Future<Report> future = executorService.submit(reportTask);
    }
}

ManagedThreadFactoryの使用

まず、バックグラウンドで実行する作業を定義するRunnableタスクを作成します。

public class ReportTask implements Runnable {

    Logger logger = Logger.getLogger(getClass().getSimpleName());

    public void run() {
        try {
            //do your background task
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            logger.log(Level.SEVERE, "Thread interrupted", e);
        }
    }
}

コンテナー管理スレッドを取得するには、ManagedThreadFactoryに新しいスレッドを要求し、それにRunnableインスタンスを渡すだけです。スレッドを開始するには、start()を呼び出します。

@Stateless
public class ReportBean {

    @Resource
    private ManagedThreadFactory threadFactory;

    public void runReports() {
        ReportTask reportTask = new ReportTask();
        Thread thread = threadFactory.newThread(reportTask);
        thread.start();
    }
}
59
Chris Ritchie

これらの制限は、主にJava EEおよびEJBが透過的なクラスタリングをサポートする必要があるために適用されます。たとえば、これらの変更は他のサーバーに簡単にミラーリングできないため、クラスターの1つのサーバーでファイルを変更しないでください。スレッドには、クラスターごとまたはサーバーごとに1つのスレッドがあるべきかという問題があります。これらのスレッドも、アプリケーションサーバーで簡単に監視することはできません。

つまり、通常のアプリケーションと同じように、Java EEサーバー)でスレッドやソケット接続を作成したり、ファイルシステムにアクセスしたりできるようにする必要があります。

4
Jörn Horstmann