Спецификация Java EE и многопоточность

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

Ответ 1

Этот вопрос возникает раз в то время.

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

Тем не менее, есть способы генерировать потоки, особенно в Weblogic с WorkManager.

Смотрите следующие вопросы:

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

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

Ответ 2

Рекомендуемый способ создания потоков в среде Java EE с помощью Concurrency Utils API, который является частью спецификации 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();
    }
}

Ответ 3

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

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