2012-03-31 2 views
3

내 코드 :블록 현재의 thread가

private AtomicBoolean fetched1 = new AtomicBoolean(false); 

    private int rowCount; 

    public int getRowCount() { 
      data.getRealm().exec(new Runnable(){ 
       @Override 
       public void run() { 
        rowCount = data.size(); 
        fetched1.set(true); 
       } 
      }); 
      while(!fetched1.get()){ 
      } 
      fetched1.set(false); 
      return rowCount; 
     } 

이 지금 나를 위해 일을 보인다,하지만 난 스레딩에 익숙하지 않은 오전한다 (항상 저를 혼동) 나는 위의 코드를 어쨌든 좋아하니?

답변

7

위의 코드를 어쨌든 사용해야합니까?

이것은 불필요한 CPU를 사용하는 스핀 루프처럼 보입니다. 데이터가 반입되었다는 신호를 보내려면 waitnotify을 사용하는 것이 좋습니다. 같은 뭔가 :

private final Object lock = new Object(); 
    private volatile Integer rowCount = null; 
    ... 

     public void run() { 
     rowCount = data.size(); 
     synchronized (lock) { 
      lock.notify(); 
     } 
     } 

    synchronized (lock) { 
    // we loop here in case of race conditions or spurious interrupts 
    while (rowCount == null) { 
     lock.wait(); 
    } 
    } 
    ... 

난 당신이 전혀 인출 AtomicBoolean 필요하다고 생각하지 않습니다. rowCountvolatile으로 설정해야하며 그 값을 테스트 할 수 있습니다. while 루프는 생산자/소비자 경쟁 조건 및 가짜 인터럽트 때문에 따라야 할 좋은 패턴입니다.

+0

'fetched.set (true);가 누락 된 것 같아요. –

+0

@Peter 감사합니다. 나는 페칭 된 것을 사용할 필요성을 제거했다. – Gray

+0

필드를 업데이트/동기화 된 블록으로 이동했습니다. 이 경우 단순하지만 더 복잡한 경우에는 필요할 것입니다. –

4

당신은 두 가지 문제

  • 첫 번째 스레드가 보통 바람직하지 않다 바쁜 대기입니다.
  • 두 번째 스레드가 값을 true로 설정하려고 시도 할 수 있으므로 패턴을 더 많은 스레드로 확장 할 수 없습니다.

대신 가장 간단한 패턴은 개체를 잠그고 값이 변경되면 대기/알림을 보내는 것입니다.

관련 문제