2017-05-16 5 views
0

notify() 및 wait()를 사용하려고합니다. 여기 내 원하는 수업이 있습니다. addNewItem()으로 전화를 걸 때 문제가 있습니다. tryToReadItem()을 먼저 호출 한 다음 addNewItem() 메서드를 호출하면 해당 로그가 인쇄되지 않습니다. 내 DemoClass이 싱글 톤입니다. 내가 모르는 뭔가가Android notify() 메소드가 호출되지 않았습니다.

DemoClass executor = DemoClass.getInstance(); 
boolean bool = executor.addNewItem(); 

암 : 여기

public class DemoClass { 

private static final String TAG = "DemoClass"; 

private static DemoClass instance; 
private Object lock = new Object(); 
private static Thread executor; 
private static Runnable reader; 
static MyQueue queue; 


private DemoClass() { 
    queue = MyQueue.getInstance(); 
    reader = new Runnable() { 

     @Override 
     public void run() { 
      tryToReadRequest(); 
     } 
    }; 

} 

public static DemoClass getInstance() { 
    if (null == instance) { 
     instance = new RequestExecutor(); 
     executor = new Thread(reader); 
     executor.run(); 
    } 
    return instance; 
} 

public boolean addNewItem() { 
    synchronized (lock) { 
     lock.notify(); // executor will be run 
     Log.i(TAG, "executor run..."); 
    } 
    return true; 
} 

public void tryToReadItem() { 

    try { 
     while (true) { 
      synchronized (lock) { 
       if (queue.checkTopValue() == null) { 
        Log.v(TAG, "queue is empty"); 
        lock.wait(); 
       } else { 
        //TODO other code... 
       } 

      } 
     } 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 
} 

해당 클래스의 사용인가?

편집 : 방금 코드를 변경했습니다. 이제 tryToReadRequest()은 queue가 비어 있지 않은 동안 계속 실행됩니다. 하지만 내 문제는 라인 lock.notify();이 실행되지 않는다는 것입니다.

+0

모두 같은 스레드에 있습니다. 다른 스레드가 관련되어야합니다. – Enzokie

+0

당신이 notifyAll에게 통보를 변경하면 같은 결과가있는 것 같군요, 맞습니까? – DEADMC

+0

문제와 관련이 없지만 적절한 싱글 톤을 위해서는 getInstance() 및 e.printStackTrace()에서 synchronized 블록이 필요합니다. 안드로이드에서 작동하지 않는다면, 대신 Log.e ("tag", Log.getStackTraceString (e))를 써야만합니다. – DEADMC

답변

0

모든

 if (queue.checkTopValue() == null) { 
      Log.v(TAG, "queue is empty"); 
      lock.wait(); 
     } 

먼저 official documentation

주에 따라 다름이 코드에 많은 문제가 있습니다 : 항상 조건 에 대한 테스트를 기다렸다되고있는 루프 내에서 대기를 호출 에 대한. 기다리는 특정 상태에 대한 인터럽트가 있다고 생각하지 마십시오. 또는 조건이 인 경우를 여전히 참이라고 가정하지 마십시오.

DemoClassSingleton입니다. 그러나Singleton

안전하지 스레드를 다중 스레드 널 (null)을 통과 할 수 있기 때문에 ==

if (null == instance) { 
     instance = new RequestExecutor(); 
     executor = new Thread(reader); 
     executor.run(); 
    } 

오른쪽 방법은 추가로 동기화 된 블록에서 확인 및 휘발성 인스턴스를 사용하는 같은 시간에 인스턴스 상태.

그렇게

private static volatile DemoClass instance; 

예를

에 휘발성 추가의 getInstance를 (다시) 방법을 뭔가이

public static DemoClass getInstance() { 
    DemoClass localInstance = instance; 

    if (localInstance == null) { 
     synchronized (DemoClass.class) { 
      localInstance = instance; 
      if (localInstance == null) { 
       localInstance = new DemoClass(); 
       instance = localInstance; 
       executor = new Thread(reader); 
       executor.run(); 
      } 
     } 
    } 
    return localInstance; 
} 

메모와 같은, 당신은 단지 내부 동기화 체크 블록을 남길 수 있습니다,하지만 getInstance 메소드를 만들 것입니다 너무 느린.