Я пишу приложение Java EE, используя Struts и Spring. В одной из операций происходит большая обработка базы данных и, следовательно, проблемы с производительностью. Что я хочу знать, могу ли я использовать многопоточность здесь? Я думаю, что спецификация Java EE не позволяет создавать собственные потоки отдельно от созданных сервером (я использую Weblogic). Пожалуйста, провери меня через это.
Спецификация Java EE и многопоточность
Ответ 1
Этот вопрос возникает раз в то время.
Согласно спецификации, он не авторизован. Лучшая страница для просмотра: Q/A: Ограничения J2EE
Тем не менее, есть способы генерировать потоки, особенно в Weblogic с WorkManager
.
Смотрите следующие вопросы:
- Как EJB может распараллелить длительный интенсивный процесс?
- Почему нереста потоков в контейнере J2EE не рекомендуется?
- Программисты J2EE не записывают файлы
Тот факт, что первый из них нацелен на 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, как в обычном приложении.