等待另一个线程中的邮件发送完成

时间:2014-07-31 15:57:30

标签: java multithreading javamail

我遇到了一个我无法解决的问题。我有我的主线程,其中我想

  1. 发送附件附件的电子邮件
  2. 删除附加的文件
  3. 按此顺序。我的问题是我正在使用一个我无法控制的电子邮件帮助程序,它会生成另一个执行发送的线程。因此,我的文件在完成附加之前被删除,并且我在邮件程序中收到FNF错误。我希望找到一种方法让我的主线程等到文件完成附加。我不知道需要多长时间。我无法控制其他线程创建,因此我无法使用join()。我可以使用Transport或者等待方法/类中的所有线程停止的方法吗?

    我的程序布局是

    //do stuff
    MailHelper.sendMail(...); //thread is created somewhere in this method
    deleteFiles(); //this happens before sendMail is finished!
    

    我需要使用Java 6.最糟糕的情况我可以让我的主线程休眠几秒钟,但这是不理想的。任何帮助表示赞赏

2 个答案:

答案 0 :(得分:2)

这是一个有趣的问题!基本上你想等待所有子线程完成,但无法控制它们。

以下是使用ThreadGroup

的技术演示

假设您有MailHelper这样的课程:

public class MailHelper {

    public void sendMail(){
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("MailHelper: Sending mail for 6s");
                for(int i = 0; i < 6; i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(".");
                }
                System.out.println("MailHelper: Sent mail!");
            }
        });
        t.start();
    }

}

然后我们的Main课程演示如何使用它:

public class Main {

    public static void main(String[] args) throws InterruptedException {
        final MailHelper mh = new MailHelper();

        ThreadGroup mailThreadGroup = new ThreadGroup("mailGroup");
        Thread callSendmailThread = new Thread(mailThreadGroup, new Runnable() {

            @Override
            public void run() {
                System.out.println("Calling sendMail().");
                mh.sendMail();
                System.out.println("sendMail() returned.");
            }
        });
        callSendmailThread.start();
        callSendmailThread.join();
        System.out.println("callSendmailThread joined. Waiting for rest of ThreadGroup to finish.");

        // We cannot rely on ThreadGroup.activeCount() to give us an accurate number, and it could be zero!
        Thread[] mailThreads = new Thread[mailThreadGroup.activeCount() + 1];
        //Therefore retry enumerate until our array was large enough to hold all
        while ( mailThreadGroup.enumerate( mailThreads, true ) == mailThreads.length ) {
            mailThreads = new Thread[ mailThreads.length * 2 ];
        }

        for(Thread t : mailThreads){
            if(t != null && t.isAlive()){
                System.out.println("Joining thread " + t.getName());
                t.join();
                System.out.println("Thread " + t.getName() + " joined.");
            }
        }
        mailThreadGroup.destroy();
        System.out.println("Done!");

    }
}

输出:

Calling sendMail().
sendMail() returned.
callSendmailThread joined. Waiting for rest of ThreadGroup to finish.
Joining thread Thread-1
MailHelper: Sending mail for 6s
.
.
.
.
.
.
MailHelper: Sent mail!
Thread Thread-1 joined.
Done!

请注意,必须确保在枚举ThreadGroup时实际启动Thread-1,因此加入callSendMailThread是绝对必要的。否则你会遇到竞争条件。

另请注意,必须通过重试多次枚举所有项目来计算ThreadGroup.enumerate() {{1}}。

答案 1 :(得分:0)

逻辑上解决问题的简单方法是跟踪邮件是否成功发送。 它可以通过以下任何一种来完成 1)在从其他线程发送邮件后设置一个具有某个值的全局变量,并在删除附件后重置它的值 2)您也可以尝试创建文件而不是变量

谢谢,
Mukeshkoshym