Спецификация Java EE и многопоточность - PullRequest
26 голосов
/ 09 июля 2010

Я пишу приложение Java EE, используя Struts и Spring. В одной из операций происходит интенсивная обработка базы данных и, следовательно, проблемы с производительностью. Что я хочу знать, могу ли я использовать многопоточность здесь? Я думаю, что спецификация Java EE не позволяет создавать собственные потоки, кроме тех, которые созданы сервером (я использую Weblogic). Пожалуйста, проведите меня через это.

Ответы [ 3 ]

59 голосов
/ 16 октября 2013

Рекомендованный способ создания потоков в среде Java EE - это API-интерфейс Concurrency Utils, который является частью спецификации EE7.

С помощью этого API будет создан новый поток, который будет управлятьсяконтейнер, гарантирующий, что все службы EE доступны для вашего потока (например, безопасность, транзакции).

Примеры ниже взяты с моего собственного сайта здесь и здесь

Использование 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();
    }
}

Затем нам нужно вызвать задачу, передав ее в метод submit () ManagedExecutorService..

@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();
    }
}
7 голосов
/ 09 июля 2010

Этот вопрос всплывает время от времени.

Согласно спецификации это не разрешено. Лучшая страница для просмотра - эта: Q / A: J2EE Ограничения

Тем не менее, есть способы порождения потоков, особенно в Weblogic с WorkManager.

Смотрите эти вопросы:

Тот факт, что первый нацелен на EJB, не должен иметь большого значения, а последний о доступе к файловой системе связан с общими ограничениями.

Надеюсь, это поможет.

4 голосов
/ 09 июля 2010

Эти ограничения действуют в основном потому, что Java EE и EJB хотят поддерживать прозрачную кластеризацию. Например, один сервер кластера не должен изменять файлы, потому что эти изменения не могут быть легко отражены на другие серверы. Для потоков есть вопрос, должен ли быть один поток на кластер или на сервер. Эти потоки также не могут быть легко отслежены сервером приложений.

При этом должна быть возможность создавать потоки, соединения с сокетами или обращаться к файловой системе на сервере Java EE, как в обычном приложении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...