当前位置: 首页 > 面试题库 >

Java如何知道其他线程是否已完成?

佴阳辉
2023-03-14
问题内容

我有一个名为的方法的对象,该方法StartDownload()启动三个线程。

每个线程执行完毕后,如何获得通知?

有没有办法知道一个(或全部)线程是否已完成或仍在执行?


问题答案:

你可以通过多种方式执行此操作:

  1. 在主线程中使用Thread.join()以阻塞方式等待每个线程完成,或者
  2. 以轮询方式(通常不鼓励使用)检查Thread.isAlive(),等待每个线程完成,或者
  3. 非常规的,对于每个有问题的线程,调用setUncaughtExceptionHandler来调用对象中的方法,并对每个线程进行编程以在完成时抛出未捕获的Exception,或者
  4. 使用java.util.concurrent中的锁或同步器或机制,或者
  5. 更传统的做法是,在主线程中创建一个侦听器,然后对每个线程进行编程以告知侦听器它们已完成。
    如何实施想法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用于NotifyingThread为延长线为新的代码通常气馁。但是,我正在编码你的问题。如果你更改NotifyingThread要实现的类,Runnable则必须更改一些管理线程的代码,这非常简单。



 类似资料:
  • 在Android上有没有办法知道,如果运行我的代码的线程,是UI线程还是不是?在swing中,有来告诉我是否在UI线程上。安卓SDK里有什么功能让我知道这一点吗?

  • 我想知道记录是否更新了熊猫数据框中的日期。数据框由几列组成,其中对于A的每个值,我们有几个B的值,包括开始日期和结束日期。由于时间戳,我们可以知道是否有新的记录或以前的记录已被修改。 我想知道的是如何能够检查如果一个新记录有一个日期范围接近其他记录在其组中例如B1组如果他们有一个类似的日期范围删除前一个只留下新记录已更新,但如果它没有公共范围来解释为新记录。 例如 输入数据帧: 预期输出: 谢谢你

  • 我正在编写一个在运行时将卡片(JPanel)添加到CardLayout的应用程序。问题是卡上的一些组件加载速度比其他组件快,使其看起来有问题,并且在显示之前没有正确渲染。 我希望它在第一次展示时准备好。 我通过加载屏幕暂时解决了这个问题,它使线程Hibernate1500毫秒。有没有更有效的方法来知道面板上的所有内容是否都已加载?

  • 问题内容: 我想检查活动是否正在运行或完成。有什么方法可以检查活动状态? 我找到了,但是我不确定。 问题答案: 如果您想执行任何步骤,将变得不可见。 他们是这里的几种选择。 onDestroy() -进行最终清理。 isFinishing() - 调用后立即返回true。 onStop() -当被框架进程终止时。(未销毁) onPause() -当被其他覆盖 onBackPressed() -捕获

  • 我在Unity中有项目,使用Mapbox, Mapbox包含以下支持库:support-v4-25.1.0.aar 此库以.aar文件的形式提供,而不是作为gradle命令 尝试构建项目时,我收到此错误: 无法确定任务的依赖项:启动程序:lintVitalRelease。< br >无法解析配置的所有项目:launcher:debuguntimeclass path。< br >无法转换支持-v4

  • 问题内容: 是否可以 不 尝试加载就知道是否已加载Java类?尝试加载该类,但我不希望出现这种副作用。还有另一种方法吗? (我不想覆盖类加载器。我正在寻找一个相对简单的方法。) 问题答案: (感谢Aleksi)此代码: 产生: 请注意,示例类不在软件包中。完整的二进制名称是必需的。 二进制名称的一个示例是