2013-06-17 2 views
0

두 개의 스레드가 있으며 현재 동기화 된 블록 내에서 개체의 notify() 및 wait() 메서드를 사용하여 잠금을 수행하고 있습니다. 나는 메인 스레드가 너무 차단되지 않습니다 나는이 방법 부울 사용 있는지 확인하고 싶었 (에만 관련 코드를 제공합니다.)동기화 된 블록 및 잠금

//Just to explain an example queue 
private Queue<CustomClass> queue = new Queue(); 

//this is the BOOLEAN 
private boolean isRunning = false; 

private Object lock; 

public void doTask(){ 
     ExecutorService service = Executors.newCachedThreadPool(); 

      //the invocation of the second thread!! 
      service.execute(new Runnable() { 
       @Override 
       public void run() { 
         while(true){ 
          if (queue.isEmpty()){ 
           synchronized (lock){ 
            isRunning = false; //usage of boolean 
            lock.wait(); 
           } 
          } 
          else{ 
           process(queue.remove()); 
          } 
         } 
       }); 

} 

//will be called from a single thread but multiple times. 
public void addToQueue(CustomClass custObj){ 


     queue.add(custObj); 
     //I don't want blocking here!! 
     if (!isRunning){ 
      isRunning = true;  //usage of BOOLEAN!  
      synchronized(lock){ 
      lock.notify(); 
      } 
     } 
} 

가 일이 잘못 여기 보인다합니까? 감사. 편집 : 목적 : add()가 두 번째 이상 호출 될 때이 방법은 notify()에서 차단되지 않습니다. 주 스레드의 비 차단 동작을 달성하는 더 좋은 방법이 있습니까?

+4

흠, BlockingQueue '? – fge

+2

'isRunning'을'volatile '으로 표시하면 두 스레드에서 액세스 할 수 있습니다 –

+0

무엇이 문제입니까? –

답변

0

addToQueue 코드를 표시하지는 않지만 모든 동기화가없는 공유 대기열 (스레드로부터 안전하지 않은)에 액세스 할 때이 코드가 제대로 작동하지 않는다고 확신합니다. 대신 사용자 정의 큐 작업을 만들려고 노력의

process(queue.remove()); 

, 시간과 작업을 저장하고 JDK에서 제공하는 BlockingQueues 또는 ConcurrentLinkedQueue 중 하나를 사용합니다 (I는 부울 플래그 계획이 가능하다는 것을 의심).

+0

addToQueue 코드가 표시됩니다. 프로세스 코드가 보이지 않습니다. –

+0

예. 이제 LinkedBlockingQueue를 사용하려고합니다. –

+0

Oi - me me on : 코드 섹션에서 아래로 스크롤하는 걸 잊었습니다. (. – Pyranja

0

대기열이 동기화되어 있지 않으므로 위의 코드는 조건부 변수 및 모니터의 일반적인 깨우기 호출로 인해 어려움을 겪을 수 있습니다. https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem 예를 들어, 다음은 문제가되는 시퀀스입니다. 실행을 시작할 때 Q는 비어 있고 isRunning은 false입니다. 스레드 1 (t1)은 Q가 비어 있는지 (true인지) 확인한 다음 실행을 중지합니다. 스레드 2 (t2)보다 실행이 시작되고 addToQ 메소드가 실행됩니다. 그런 다음 t1이 계속 실행되고 Q가 비어 있지 않아도 잠금을 기다립니다. 논 블로킹 솔루션을 원한다면 nonblocking Q 자바가 제공하는 서비스를 사용할 수있다. (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html)Of 물론 java blockingQueue를 사용할 수도 있지만 차단하고있다.)