2011-04-24 46 views
4

我在当前的android instrumentation测试中存在litte竞态条件。我要的是:如何等待java中的线程启动

  1. T1:启动线程T2
  2. T2做点事
  3. T1:与T2

加入对于步骤1和3是Android的使用生命周期事件。但由于仪器测试一切都发生得非常快,我得到:

  1. T1:启动线程T2
  2. T1:与T2(它变成是一个空操作)
  3. T2加入做点事

当然,我可以添加一些睡眠,以获得所需的行为,但我不知道是否有更好的方法来做到这一点。即有没有办法确保只有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 

正如我所说的:无操作时,因为线程尚未启动。

+0

不会使敏感'Thread.join()'等待连接的线程死掉(除非你设置一个很短的超时)。你确定这个错误不是其他的吗? – Mat 2011-04-24 14:56:04

+0

问题不在于单元测试的速度 - 这是线程调度正在进行的方式。 – jefflunt 2011-04-24 15:09:06

+0

@Mat:我添加了一个代码示例来回答这个问题。 – Martin 2011-04-24 15:19:15

回答

11

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

如果要同步多个线程的启动,您还可以使用CyclicBarrier

+0

谢谢! CountDownLatch和CyclicBarrier正是我在找的地方。 CountDownLatch为当前问题。和CyclicBarrier我记住将来使用它,因为它提供了Ada的会合的基本功能,我一直认为它是所有多任务范例中最好的。 – Martin 2011-04-24 15:22:23

0

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 
    ... 

    }     
} 
+1

注意:从OOP的角度来看,最好是实现Runnable而不是扩展Thread本身。 – Voo 2011-04-24 16:25:54

+0

对不起,我应该强调一个事实,即我正在谈论一个意味着“控制反转”的Android仪器测试。第一步是onStart实时循环事件,第三步是onDestroy。 'this.thread!= null'是因为有一点不平衡(onCreate,onStart,onDestroy但没有onStop),并且onDestroy可能在没有inStart的情况下被调用。 – Martin 2011-04-24 17:49:59