2010-01-20 18 views
9

Estoy escribiendo una aplicación donde el usuario puede agregar y eliminar a otros usuarios como amigos. Mi página tiene una lista de usuarios diferentes y cada usuario recibe un botón para agregarlos a la lista de amigos. Estoy enviando una solicitud de AJAX al servlet de Java para agregar al usuario seleccionado como amigo. Estoy mostrando un mensaje de alerta en la interfaz de usuario para mostrar el resultado del proceso.Ejecutar el proceso de fondo en diferentes hilos en Java

Mi problema es que tengo que enviar un correo electrónico cuando el usuario se agrega como amigo este código está escrito en el mismo método en el servlet.

Debido a este fragmento de código, mi mensaje de alerta llega muy tarde.

Necesito ejecutar un pthread por separado para ejecutar esta función de envío de correo para que una vez que se agregue el usuario obtenga el resultado y el correo se envíe en un proceso por separado.

Mi código en el servlet es

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."; 
    } 
} 

Respuesta

0

leer la documentación en

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

Debe subclase java.lang.Thread la implementación de su método run. Probablemente sea como su actual SendMail. Luego llama al método start en el hilo, y el control vuelve inmediatamente a la siguiente línea de código mientras el hilo se ejecuta en segundo plano.

+2

Una forma preferida sería definir una clase que implementa Ejecutable y luego construir un hilo que pasa en el ejemplo Ejecutable. Sub-classing Thread es una forma de herencia de implementación y generalmente no se recomienda. – Adamski

14

No estoy seguro de que este sea el problema. Enviar un correo electrónico no es una operación tan costosa, solo informa al servidor SMTP que el correo debe ser enviado, y el servidor SMTP se ocupa desde ese momento.

Aún así, usted podría intentar:

new Thread(new Runnable() { 
    public void run() { 
     MailUtility.send(inviteeUser.getUserEmailAddress().trim(), 
      "[email protected]", "add friend message", Utility 
        .getAddFriendMessageBody(LoginHelper 
          .getLoggedInUserEmail()), false); 
    } 
}).start(); 
+0

Para mí, enviar un correo electrónico es una operación costosa – gstackoverflow

11

me gustaría sugerir que define un ExecutorService dentro de su servlet y luego presentar una Runnable o Callable al servicio con el fin de realizar el trabajo de enviar el correo electrónico.

private ExecutorService execService = Executors.newFixedThreadPool(1); 

... 

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

ventajas de este enfoque incluyen:

  • no se realiza la operación costosa de crear un nuevo Thread cada vez.
  • Mantiene un mayor control sobre los # hilos en ejecución en su servlet (ya que las solicitudes de correo electrónico simplemente se ponen en cola).
  • El manejo de errores se puede centralizar, ya sea subclasificando ThreadPoolExecutor y redefiniendo afterExecute(Runnable, Throwable) o definiendo un CompletionService para inspeccionar los resultados de cada Runnable completado.
  • Su cadena de llamada se remite a un futuro, que puede usarse potencialmente para ordenar los resultados o bloquearlos hasta que se complete el cálculo asincrónico.
5

bastante simple en Java 5 o superior:

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(), 
       "[email protected]", "add friend message", Utility 
        .getAddFriendMessageBody(LoginHelper 
          .getLoggedInUserEmail()), false); 
     } 
    }); 
} 

ps.puede que necesite hacer algunas variables definitivas para que se puedan usar dentro del ejecutable, pero lo dejaré como un ejercicio para el lector :)

1

Otra opción para hacer su tarea (enviar un correo electrónico en segundo plano) es tener otro programa pequeño (puede ser un daemon) que leerá periódicamente la Tabla especial en DB y enviará un correo electrónico. El programa puede escribirse en cualquier idioma y comenzar con el proceso en segundo plano del sistema operativo.

Aquí es las ventajas de hacerlo de esa manera:

  1. Es posible utilizar hwatever te gusta escribir un demonio tales.
  2. Puede controlar el comportamiento de dicho daemon: para detectar cuando dos personas intentan sumarse a sus amigos.
  3. Rendimiento - el envío de correos electrónicos puede abusar del servidor (especialmente la interfaz de red). Al tener un daemon de este tipo, puede instalarlo en un servidor diferente con una interfaz de red diferente.
  4. ....
Cuestiones relacionadas