Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中的不同线程中运行后台进程_Java_Multithreading - Fatal编程技术网

在Java中的不同线程中运行后台进程

在Java中的不同线程中运行后台进程,java,multithreading,Java,Multithreading,我正在编写一个应用程序,用户可以添加和删除其他用户作为朋友。 我的页面有一个不同用户的列表,每个用户都有一个按钮,可以将他们添加到朋友列表中。 我正在向Javaservlet发送一个AJAX请求,以将所选用户添加为好友。 我在UI上显示警报消息以显示处理结果 我的问题是,当用户被添加为好友时,我必须发送一封邮件。这段代码是用servlet中相同的方法编写的 由于这段代码,我的警告信息来得很晚 我需要运行一个单独的pthread来运行这个sendmail函数,这样一旦添加了用户,我就会得到结果,邮

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

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

由于这段代码,我的警告信息来得很晚

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

我在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(),
            "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.";
    }
}

请阅读位于的文档

您应该将java.lang.Thread子类化以实现run方法。它可能与您当前的sendMail类似。
然后在线程上调用start方法,当线程在后台执行时,控件立即返回到下一行代码。

我不确定这是否是问题所在。发送电子邮件并不是那么昂贵的操作——它只是通知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();

我建议在servlet中定义一个
ExecutorService
,然后向该服务提交一个
Runnable
Callable
,以执行发送电子邮件的工作

private ExecutorService execService = Executors.newFixedThreadPool(1);

...

execService.submit(new Runnable()) {
  public void run() {
    // Send email.
  }
};
这种方法的优点包括:

  • 您不会每次都执行创建新
    线程的昂贵操作
  • 您可以更好地控制servlet中运行的线程总数(因为电子邮件请求只是排队)
  • 可以通过子类化
    ThreadPoolExecutor
    和重写
    afterExecute(Runnable,Throwable)
    或者通过定义
    CompletionService
    来检查每个完成的
    Runnable
    的结果来集中错误处理
  • 您的调用线程被传回一个未来线程,该线程可能被用于将结果打包或阻止,直到异步计算完成

在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);
         }
    });
}

另外,您可能需要将一些变量设置为final,以便在runnable中使用,但我将把它作为练习留给读者:)

另一个执行任务的选项(在后台发送电子邮件)是使用另一个小程序(可能是守护进程),该程序将定期读取数据库中的特殊表并发送电子邮件。程序可以用任何语言编写,并且可以在OS后台进程中启动

这样做的好处如下:

  • 您可以使用hwatever编写这样的守护程序
  • 您可以控制这样的守护进程的行为:当两个人试图将彼此添加到好友时进行检测
  • 性能-发送电子邮件可能会滥用服务器(尤其是网络接口)。有了这样一个守护进程,您可以将其安装在具有不同网络接口的不同服务器上

  • 首选的方法是定义一个实现Runnable的类,然后构造一个传入Runnable实例的线程。子分类线程是实现继承的一种形式,通常不建议使用。对我来说,发送电子邮件是一项昂贵的操作