2011-04-24 3 views
4

현재 안드로이드 계측 테스트에서 리트 조건이 발생했습니다. 내가 원하는 것은 :자바에서 스레드 시작을 기다리는 방법

  1. T1은 : 뭔가를 수행
  2. T1을 : 스레드 T2에게
  3. T2를 시작 안드로이드 라이브 사이클 이벤트 인 1 단계와 3으로 T2

에 가입하세요. 그러나 때문에 계측 테스트 모두가 매우 빠르게 일어나는 내가 얻을 :

  1. T1이 : 스레드 T2에게
  2. T1을 시작
  3. T2 (무 조작으로 판명) T2에 가입 : 무언가를

원하는 동작을 얻으려면 몇 가지 추가 할 수 있지만 확실히 할 수있는 방법이 있는지 궁금합니다. i.E. 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

+0

문제는 단위 테스트의 속도가 아닙니다. 스레드 스케줄링이 실행되는 방식입니다. – jefflunt

+0

@Mat :이 질문에 답하기위한 코드 샘플을 추가했습니다. – Martin

답변

11

나는 일반적으로 CountDownLatch을 사용합니다. 비동기 프로세스 테스트에 대해서는 answer을 참조하십시오.

많은 스레드의 시작을 동기화하려는 경우 CyclicBarrier을 사용할 수도 있습니다.

+0

고마워요! CountDownLatch 및 CyclicBarrier 정확히 내가 원하는 부분. 현재 문제에 대한 CountDownLatch입니다. CyclicBarrier 나는 항상 모든 멀티 태스킹 패러다임 중에서 가장 좋은 것으로 생각되는 Ada의 랑데부의 기본 기능을 제공하므로 앞으로의 사용을 염두에 두어야합니다. – Martin

0

Martin, 코드를 보면 내가 쓰레드 클래스를 사용하지 않을 수도 있다는 느낌이 들게됩니다. 특히 다른 스레드가 살아 있는지 여부를 테스트하는 것은 안티 패턴처럼 보입니다. 가장 실용적인 시나리오에서는 코드에서 this.thread.isAlive() 조건을 생략 할 수 있으며 프로그램은 계속 작동합니다.

두 개의 스레드 (두 개의 다른 작업을 수행해야 함)가 동일한 코드를 실행하고 논리적 조건 (예 : this.thread != null)을 사용하여 두 스레드 중 현재 실행중인 스레드를 결정하는 것으로 보입니다 .

일반적으로 스레드를 확장하고 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

+0

죄송합니다. "컨트롤 반전"을 의미하는 Android 계측 테스트에 대해 말하고 있다는 사실을 강조 했어야합니다. 1 단계는 onStart 라이브 사이클 이벤트이고 3 단계는 onDestroy입니다. 'in.thread! = null'은 약간의 in-balance (onCreate, onStart, onDestroy는 있지만 onStop은 없음)가 있고 inDestroy가 inStart없이 호출 될 수 있기 때문에 거기에 있습니다. – Martin

관련 문제