问题描述
我有一个对象,其方法名为 StartDownload()
,它启动三个线程.
I have an object with a method named StartDownload()
, that starts three threads.
如何在每个线程执行完毕时收到通知?
How do I get a notification when each thread has finished executing?
有没有办法知道一个(或全部)线程是否已完成或仍在执行?
Is there a way to know if one (or all) of the thread is finished or is still executing?
推荐答案
有多种方法可以做到这一点:
There are a number of ways you can do this:
- 使用 Thread.join() 在主线程中以阻塞方式等待每个线程完成,或
- 检查 Thread.isAlive() 以轮询方式——通常不鼓励——等待每个线程完成,或者
- 非常规,对于每个有问题的线程,调用 setUncaughtExceptionHandler 调用对象中的方法,并对每个线程进行编程,使其在完成时抛出未捕获的异常,或者
- 使用来自 java.util.concurrent,或
- 更正统,在你的主线程中创建一个监听器,然后对你的每个线程进行编程,告诉监听器他们已经完成了.
- Use Thread.join() in your main thread to wait in a blocking fashion for each Thread to complete, or
- Check Thread.isAlive() in a polling fashion -- generally discouraged -- to wait until each Thread has completed, or
- Unorthodox, for each Thread in question, call setUncaughtExceptionHandler to call a method in your object, and program each Thread to throw an uncaught Exception when it completes, or
- Use locks or synchronizers or mechanisms from java.util.concurrent, or
- More orthodox, create a listener in your main Thread, and then program each of your Threads to tell the listener that they have completed.
如何实施想法#5?嗯,一种方法是先创建一个接口:
How to implement Idea #5? Well, one way is to first create an interface:
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()
.因此,当他们完成时,他们会自动通知任何等待通知的人.
and then each of your Threads will extend NotifyingThread
and instead of implementing run()
it will implement doRun()
. Thus when they complete, they will automatically notify anyone waiting for notification.
最后,在您的主类中——启动所有线程(或至少是等待通知的对象)的类——修改该类以implement ThreadCompleteListener
,并在创建每个线程后立即添加自己添加到听众列表中:
Finally, in your main class -- the one that starts all the Threads (or at least the object waiting for notification) -- modify that class to implement ThreadCompleteListener
and immediately after creating each Thread add itself to the list of listeners:
NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start(); // Start the Thread
然后,当每个 Thread 退出时,您的 notifyOfThreadComplete
方法将使用刚刚完成(或崩溃)的 Thread 实例调用.
then, as each Thread exits, your notifyOfThreadComplete
method will be invoked with the Thread instance that just completed (or crashed).
请注意,对于 NotifyingThread
最好是 implements Runnable
而不是 extends Thread
因为在新代码中通常不鼓励扩展 Thread.但我正在为你的问题编码.如果您更改 NotifyingThread
类以实现 Runnable
,那么您必须更改一些管理线程的代码,这非常简单.
Note that better would be to implements Runnable
rather than extends Thread
for NotifyingThread
as extending Thread is usually discouraged in new code. But I'm coding to your question. If you change the NotifyingThread
class to implement Runnable
then you have to change some of your code that manages Threads, which is pretty straightforward to do.
这篇关于如何知道其他线程是否已完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!