【问题标题】:How to wait for the start of a thread in java如何在java中等待线程的开始
【发布时间】:2011-04-24 14:51:58
【问题描述】:

在我当前的 android 仪器测试中,我有一个小竞争条件。我想要的是:

  1. T1:启动线程 T2
  2. T2:做点什么
  3. T1:加入 T2

第 1 步和第 3 步是 Android 实时循环事件。但是因为在仪器测试中,一切都发生得非常快,我得到:

  1. T1:启动线程 T2
  2. T1:与 T2 连接(结果是无操作)
  3. T2:做点什么

当然我可以添加一些睡眠来获得所需的行为,但我想知道是否有更好的方法来做到这一点。 IE。有没有办法确保刚刚start ()-ed 的线程确实启动了,并且没有仍然坐在某个调度队列中等待启动。

(安迪男孩,我想念艾达基于集合的多任务处理)

然后回答垫子的问题:

  if (this.thread != null && this.thread.isAlive ())
  {
     this.stop.set (true);

     try
     {
        this.thread.join (1000);
     }
     catch (final InterruptedException Exception)
     {
        android.util.Log.w (Actor.TAG, "Thread did not want to join.", Exception);
     } // try
  } // if

正如我所说:no-op when 因为线程还没有开始。

【问题讨论】:

  • 这没有意义Thread.join() 等待加入的线程终止(除非您设置了非常短的超时)。您确定错误不是其他错误吗?
  • 问题不在于单元测试的速度,而是线程调度的方式。
  • @Mat:我添加了一个代码示例来回答这个问题。
  • @Martin:你为什么要在那里测试thread != null?你确定你输入的是if 声明吗?您的第二个线程是否在开始处理之前检查 stop.set(true) 设置的任何内容?
  • @Martin - 看看 - Awaitility .. 可能有用。

标签: java android multithreading


【解决方案1】:

我通常使用CountDownLatch,例如请参阅answer 测试异步进程。

如果你想同步多个线程的启动,你也可以使用CyclicBarrier

【讨论】:

  • 谢谢! CountDownLatch 和 CyclicBarrier 正是我想要的。当前问题的 CountDownLatch。 CyclicBarrier 我牢记在心以备将来使用,因为它提供了 Ada 集合点的基本功能,我一直认为这是所有多任务处理范例中最好的。
【解决方案2】:

Martin,看着您的代码,我感觉您可能没有按照设计使用的方式使用 Thread 类。特别是,测试另一个线程是否还活着似乎是一种反模式。在大多数实际情况下,您可以在代码中省略 this.thread.isAlive () 条件,程序仍然可以运行。

您似乎正试图让两个线程(应该做两件不同的事情)运行同一段代码,并且您使用逻辑条件(例如this.thread != null)来决定两个线程中的哪一个是当前正在运行。

通常,您会编写两个类,每个类都扩展 Thread 并实现 run() 方法。每个 run() 方法都实现了单个线程的逻辑。然后,您将从第一个线程启动第二个线程,并在该第二个线程上调用 join() 以等待它完成。

public class SecondThread extends Thread {
  public void run() {
    ...
  }      
}

public class FirstThread extends Thread {
  public void run() {
    // Only FirstThread is running
    ...

    SecondThread st = new SecondThread();
    st.start();

    // Now both threads are running
    ...

    st.join(); // Wait for SecondThread to complete

    // Only FirstThread is running
    ...

  }                
}

【讨论】:

  • 注意:从 OOP 的角度来看,最好实现 Runnable 而不是扩展 Thread 本身。
  • 抱歉,我应该强调一个事实,即我所说的 Android 仪器测试意味着“控制反转”。第一步是 onStart 实时循环事件,第三步是 onDestroy。 this.thread != null 之所以存在,是因为存在一些不平衡(onCreate、onStart、onDestroy 但没有 onStop),并且可能在没有 inStart 的情况下调用 onDestroy。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 2010-11-23
  • 2018-12-15
  • 2018-07-24
相关资源
最近更新 更多