Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run background process in different thread in Java

I am writing an application where user can add and remove other users as friends. My page has a list of diffrent users and each user is given with a button to add them in friend list. I am sending a AJAX request to Java servlet to add the selected user as a friend. I am showing alert message at UI to show the result of process.

My problem is i have to sent a mail when user is added as friend this code is written in the same method in the servlet.

Because of this piece of code my alert message comes very late.

I need to run a separate pthread to run this send mail function so that once user is added i will get the result and mail will be send in separate process.

My code in the Servlet is

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(),
            "[email protected]", "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.";
    }
}
like image 949
viredra-agarwal Avatar asked Jan 20 '10 09:01

viredra-agarwal


2 Answers

I'm not sure this is the problem. Sending an email is not quite that expensive operation - it just informs the SMTP server that the mail should be sent, and the SMTP server takes care from there on.

Still, you could try:

new Thread(new Runnable() {
    public void run() {
        MailUtility.send(inviteeUser.getUserEmailAddress().trim(),
            "[email protected]", "add friend message", Utility
                    .getAddFriendMessageBody(LoginHelper
                            .getLoggedInUserEmail()), false);
    }
}).start();
like image 127
Bozho Avatar answered Sep 19 '22 20:09

Bozho


I'd suggest defining an ExecutorService within your servlet and then submit a Runnable or Callable to the service in order to perform the work of sending the email.

private ExecutorService execService = Executors.newFixedThreadPool(1);

...

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

Advantages of this approach include:

  • You do not perform the expensive operation of creating a new Thread each time.
  • You retain greater control over the total #threads running in your servlet (as email requests are simply queued up).
  • Error handling can be centralised, either by subclassing ThreadPoolExecutor and overriding afterExecute(Runnable, Throwable) or by defining a CompletionService to inspect the results of each completed Runnable.
  • Your calling thread is passed back a Future, which can potentially be used to marshall the results back or block until the asynchronous computation has completed.
like image 39
Adamski Avatar answered Sep 22 '22 20:09

Adamski