Выполните фоновый процесс в другом потоке в Java

Я пишу приложение, где пользователь может добавить и удалить других пользователей как друзей. Моя страница имеет список различных пользователей, и каждому пользователю дают с кнопкой для добавления их в списке друзей. Я отправляю запрос Ajax к сервлету Java для добавления выбранного пользователя как друга. Я показываю аварийное сообщение в UI для показа результата процесса.

Моя проблема, у меня есть к отправленному почта, когда пользователь добавляется как друг, этот код написан в том же методе в сервлете.

Из-за этой части кода мое аварийное сообщение появляется очень поздно.

Я должен выполнить отдельный pthread для выполнения, это отправляет почтовую функцию так, чтобы, после того как пользователь был добавлен, я получу результат, и почта будет, отправляют в отдельном процессе.

Мой код в Сервлете

private void sendMail(long inviteeID) {
    User inviteeUser = null;
    try {
        inviteeUser = userHandler.getUser(inviteeID);
    } catch (DataException e) {
        sLog.error("User does not exist.", e);
    } catch (UserNotFoundException e) {
        sLog.error("User does not exist.", e);
    }
    MailUtility.send(inviteeUser.getUserEmailAddress().trim(),
            "vagarwal@q3tech.com", "add friend message", Utility
                    .getAddFriendMessageBody(LoginHelper
                            .getLoggedInUserEmail()), false);
}



private String inviteAsFriend(long inviteeID) {

    boolean result = false;

    if (LoginHelper.isUserLoggedIn()) {
        try {
            User user = userHandler.findUserByEmail(LoginHelper
                    .getLoggedInUserEmail());

            if (userHandler.isUserFriend(user.getUserId(), inviteeID)) {

                if (userHandler.addFriend(user, inviteeID)) {

                    result = true;
                    return "Member added successfully as your friend.";
                } else {

                    return "Member could not be added as your friend. Please try again later.";
                }

            } else {

                return "Member is already your friend.";
            }

        } catch (DataException e) {

            return "User does not exist.";
        } catch (UserNotFoundException e) {

            return "User does not exist.";
        } catch (Exception e) {

            return "Member could not be added as your friend. Please try again later.";
        } finally {
            if (result) {
                sendMail(inviteeID);
            }
        }
    } else {
        return "User not logged in.";
    }
}
9
задан Luixv 5 November 2013 в 11:26
поделиться

5 ответов

Я не уверен, что это проблема. Отправка электронной почты - это не совсем такая дорогостоящая операция - это просто информирует SMTP-сервер о том, что почта должна быть отправлена, а SMTP-сервер заботится от него.

Тем не менее, вы можете попробовать:

new Thread(new Runnable() {
    public void run() {
        MailUtility.send(inviteeUser.getUserEmailAddress().trim(),
            "vagarwal@q3tech.com", "add friend message", Utility
                    .getAddFriendMessageBody(LoginHelper
                            .getLoggedInUserEmail()), false);
    }
}).start();
14
ответ дан 4 December 2019 в 07:14
поделиться

Я бы предложил определить ExecutorService в вашем сервлете в вашем сервлете, а затем представить Runnable или Callable к услуге, чтобы выполнить работу по отправке Эл. адрес.

private ExecutorService execService = Executors.newFixedThreadPool(1);

...

execService.submit(new Runnable()) {
  public void run() {
    // Send email.
  }
};

Преимущества этого подхода включают в себя:

  • Вы не выполняете дорогую работу по созданию нового поток каждый раз.
  • Вы сохраняете большее управление в течение всего количества # на сервлетах # на сервлете (поскольку запросы электронной почты просто входят в очередь).
  • Обработка ошибок может быть централизована, либо путем подкласса ThreadPoolexecuteCuturexecutor и переопределение Afterexecute (Runnable, Remable) или путем определения завершения поставки для проверки результатов каждого Завершено Runnable .
  • Ваша тема вызова передается в будущее, что потенциально может быть использовано для маршалла результатов назад или блокировать до тех пор, пока асинхронные вычисления не будут завершены.
11
ответ дан 4 December 2019 в 07:14
поделиться

Довольно прост в Java 5 или выше:

private final ExecutorService executor = Executors.newFixedThreadPool(MAX_ALLOWED_THREADS);
private void sendMail(long inviteeID) {
    User inviteeUser = null;
    try {
        inviteeUser = userHandler.getUser(inviteeID);
    } catch (DataException e) {
        sLog.error("User does not exist.", e);
    } catch (UserNotFoundException e) {
        sLog.error("User does not exist.", e);
    }
    executor.submit(new Runnable() {
         public void run() {
            MailUtility.send(inviteeUser.getUserEmailAddress().trim(),
               "vagarwal@q3tech.com", "add friend message", Utility
                    .getAddFriendMessageBody(LoginHelper
                            .getLoggedInUserEmail()), false);
         }
    });
}

PS. Возможно, вам понадобится сделать финал переменных для того, чтобы он был использован в родительском языке, но я оставлю это как упражнение для читателя :)

5
ответ дан 4 December 2019 в 07:14
поделиться

Другой вариант для выполнения вашей задачи (для отправки электронной почты в фоновом режиме) - иметь другую небольшую программу (может быть демоном), которая будет периодически читать специальную таблицу в DB и отправить электронную почту. Программа может быть написана на любом языке и начать на фоне ОС Proccess.

Вот преимущества этого способа:

  1. Вы можете использовать Hwatever, который вам нравится писать такой демон.
  2. Вы можете контролировать как такого демона: обнаруживать, когда два человека пытаются добавить друг друга друзьям.
  3. Perfomance - отправка электронных писем может злоупотреблять сервером (особенно сетевой интерфейс). Наличие такого демона, вы можете установить его на сервере Defferent с разным сетевым интерфейсом.
  4. ....
1
ответ дан 4 December 2019 в 07:14
поделиться

Прочитайте документацию в

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/doCs/api/java/lang/thrad.html

, вы должны подкласс java.lang.thread реализует ваш метод запуска. Это, вероятно, будет похоже на ваш нынешний sendmail. Затем вы называете метод начала на потоке, а немедленно возвращается управление к следующей строке кода, пока нить выполняется в фоновом режиме.

0
ответ дан 4 December 2019 в 07:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: