我遇到了一个我无法解决的问题。我有我的主线程,其中我想
按此顺序。我的问题是我正在使用一个我无法控制的电子邮件帮助程序,它会生成另一个执行发送的线程。因此,我的文件在完成附加之前被删除,并且我在邮件程序中收到FNF错误。我希望找到一种方法让我的主线程等到文件完成附加。我不知道需要多长时间。我无法控制其他线程创建,因此我无法使用join()
。我可以使用Transport
或者等待方法/类中的所有线程停止的方法吗?
我的程序布局是
//do stuff
MailHelper.sendMail(...); //thread is created somewhere in this method
deleteFiles(); //this happens before sendMail is finished!
我需要使用Java 6.最糟糕的情况我可以让我的主线程休眠几秒钟,但这是不理想的。任何帮助表示赞赏
答案 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