2010-01-20 66 views
9

我正在编写一个应用程序,用户可以在其中添加和删除其他用户作为朋友。 我的页面有一个不同的用户列表,每个用户都有一个按钮将它们添加到好友列表中。 我正在向Java servlet发送一个AJAX请求,以将所选用户添加为朋友。 我在UI上显示警报消息以显示过程结果。在Java的不同线程中运行后台进程

我的问题是我必须发送邮件时,用户被添加为朋友这段代码是写在同一个方法在servlet中。

由于这段代码,我的警报消息来得很晚。

我需要运行一个单独的pthread来运行这个发送邮件函数,这样一旦用户被添加,我将得到结果,邮件将在单独的进程中发送。

我在Servlet代码

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

回答

0

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

阅读文档,您应该继承java.lang.Thread中实现你的run方法。它可能会像你当前的sendMail。 然后您调用线程上的方法start,并且控制权在线程在后台执行时立即返回到下一行代码。

+2

一种优选的方法是定义一个实现Runnable一个类,然后构造一个线程传递了Runnable实例。子分类线程是一种实现继承的形式,通常不推荐使用。 – Adamski 2010-01-20 09:36:40

14

我不确定这是问题所在。发送电子邮件并不是那么昂贵的操作 - 它只是通知SMTP服务器应该发送邮件,并且SMTP服务器从那里开始处理。

不过,你可以尝试:

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

对我来说,发送电子邮件的操作非常昂贵 – gstackoverflow 2015-09-06 13:27:10

11

我建议你的servlet中定义的ExecutorService,然后提交一个RunnableCallable到服务,以便执行发送电子邮件的工作。这种方法的

private ExecutorService execService = Executors.newFixedThreadPool(1); 

... 

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

优点包括:

  • 你不执行每次都创建一个新的Thread的昂贵的操作。
  • 您可以更好地控制servlet中运行的总线数(因为电子邮件请求只是排队等待)。
  • 通过继承ThreadPoolExecutor和覆盖afterExecute(Runnable, Throwable)或定义CompletionService来检查每个完成的Runnable的结果,可以集中错误处理。
  • 您的调用线程传回Future,它可能用于将结果集中回或阻塞,直到异步计算完成。
5

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

PS。你可能需要做一些最后的变量,以便它是可运行的内部使用,但我会离开这个作为一个练习留给读者:)

1

另一种选择做你的任务(发送电子邮件背景)是有另一个小程序(可能是一个守护进程),这将定期读取特殊的表在DB和发送电子邮件。程序可以用任何语言编写,并从OS后台进程开始。

这里是做这样的优点:

  1. 您可以使用hwatever你喜欢写这样的守护进程。
  2. 您可以控制这种守护进程的behaivor:当两个人试图相互加为好友来检测。
  3. 性能比较 - 发送电子邮件可能会滥用服务器(尤其是网络接口)。有了这样一个守护进程,你可以将它安装在具有不同网络接口的不同服务器上。
  4. ....