我有一个对象,其方法名为StartDownload()
,启动三个线程。
当每个线程执行完毕时如何收到通知?
有没有办法知道一个(或全部)线程是否已完成或仍在执行?
您可以通过多种方式执行此操作:
- Use 线程.join() http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#join()在主线程中以阻塞方式等待每个线程完成,或者
- Check 线程.isAlive() http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#isAlive()以轮询方式(通常不鼓励)等待每个线程完成,或者
- 非正统,对于每个有问题的线程,调用setUncaughtExceptionHandler http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#setUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler)调用对象中的方法,并对每个线程进行编程,使其在完成时抛出未捕获的异常,或者
- 使用锁、同步器或机制java.util.concurrent http://java.sun.com/javase/6/docs/api/java/util/concurrent/package-summary.html, or
- 更正统的是,在主线程中创建一个侦听器,然后对每个线程进行编程以告诉侦听器它们已完成。
如何实施想法#5?好吧,一种方法是首先创建一个接口:
public interface ThreadCompleteListener {
void notifyOfThreadComplete(final Thread thread);
}
然后创建以下类:
public abstract class NotifyingThread extends Thread {
private final Set<ThreadCompleteListener> listeners
= new CopyOnWriteArraySet<ThreadCompleteListener>();
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
private final void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.notifyOfThreadComplete(this);
}
}
@Override
public final void run() {
try {
doRun();
} finally {
notifyListeners();
}
}
public abstract void doRun();
}
然后你的每个线程都会扩展NotifyingThread
而不是实施run()
它将实施doRun()
。因此,当它们完成时,它们会自动通知任何等待通知的人。
最后,在你的主类中——启动所有线程(或者至少是等待通知的对象)——将该类修改为implement ThreadCompleteListener
创建每个线程后立即将其自身添加到侦听器列表中:
NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start(); // Start the Thread
然后,当每个线程退出时,你的notifyOfThreadComplete
方法将使用刚刚完成(或崩溃)的 Thread 实例调用。
请注意,更好的是implements Runnable
而不是extends Thread
for NotifyingThread
因为在新代码中通常不鼓励扩展线程。但我正在针对你的问题进行编码。如果您更改NotifyingThread
要实现的类Runnable
那么您必须更改一些管理线程的代码,这非常简单。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)