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

Java 等待另一个线程中的邮件发送完成,java,multithreading,jakarta-mail,Java,Multithreading,Jakarta Mail,我有个问题我真的搞不懂。我有我的主线,我想在其中 发送带有附件的电子邮件 删除附加的文件 按这个顺序。我的问题是,我正在使用一个我无法控制的电子邮件助手,它会生成另一个执行发送的线程。因此,我的文件在附加之前就被删除了,我的邮件中出现了FNF错误。我正在寻找一种方法,使我的主线程等待,直到文件完成被附加。我不知道需要多长时间。我无法控制其他线程的创建,因此无法使用join()。我是否可以使用传输或者等待方法/类中的所有线程停止的方法 我的程序的布局是 //do stuff MailHelper.

我有个问题我真的搞不懂。我有我的主线,我想在其中

  • 发送带有附件的电子邮件
  • 删除附加的文件
  • 按这个顺序。我的问题是,我正在使用一个我无法控制的电子邮件助手,它会生成另一个执行发送的线程。因此,我的文件在附加之前就被删除了,我的邮件中出现了FNF错误。我正在寻找一种方法,使我的主线程等待,直到文件完成被附加。我不知道需要多长时间。我无法控制其他线程的创建,因此无法使用
    join()
    。我是否可以使用
    传输
    或者等待方法/类中的所有线程停止的方法

    我的程序的布局是

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

    我需要使用Java6。最糟糕的情况是,我可以让我的主线程睡眠几秒钟,但那是不可能的。感谢您的帮助

    逻辑上解决问题的简单方法是跟踪邮件是否成功发送。 它可以通过以下任何一种方式完成

    1) 在从其他线程发送邮件后,使用某个值设置全局变量,并在删除附件后将其重置为值。
    2) 您也可以尝试创建一个文件,而不是变量。


    谢谢你,

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

    下面是使用以下方法演示该技术:

    假设您有这样一个
    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();
        }
    
    }
    
    输出:

    调用sendMail()。
    返回了sendMail()。
    callSendmailThread已加入。正在等待线程组的其余部分完成。
    连接螺纹螺纹-1
    MailHelper:发送邮件6秒
    .
    .
    .
    .
    .
    .
    邮件助手:已发送邮件!
    螺纹-1已接合。
    完成!
    
    请注意,必须确保在枚举线程组时实际启动了
    Thread-1
    ,因此加入
    callSendMailThread
    是绝对必要的。否则你会得到一个比赛条件


    还请注意,必须通过多次尝试枚举所有项目来说明
    ThreadGroup.enumerate()
    的错误。

    MailHelper是否向您指示发送已完成?你能连接一个监听器吗?不,不能。我根本无法修改类。你怎么知道邮件已发送?你有什么办法来检查吗?听起来你运气不好,用一个更好的邮件发送器。伙计们,我一直在想,也许有一个解决方案-如果我创建了一个新的
    线程组
    ,创建了一个调用
    sendMail()
    的新线程,并将该线程放入线程组,会怎么样。然后我会在该线程上进行连接-在该线程完成后,我正在尝试等待的新线程将被创建,因此我将获得该
    线程组中的所有线程,并在所有线程上进行连接-然后当它们都完成后,我可以继续!这听起来合理吗?我以前从未使用过
    ThreadGroup
    ,所以我的推理可能不正确。我从来都不喜欢全局变量。我最终做的就是,我忘了发布我的最终解决方案,回答得好!
    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!");
    
        }
    }