2016-07-03 8 views
2

저는 장벽 점을 시뮬레이트하는이 클래스를 작성하고 있습니다. 스레드가이 장벽 지점에 도달하면 다른 스레드도이 지점에 도달 할 때까지 진행할 수 없습니다. 이 시점에 도착한 스레드 수를 추적하기 위해 카운터를 사용하고 있습니다. 클래스가 N + 1 개의 쓰레드를 기대하지만 N 개의 쓰레드 만 주어진다고 가정하자. 이 경우 프로그램은 도착할 스레드가 하나 더 있다고 생각하기 때문에 모든 스레드를 대기 상태로 유지합니다.기다리는 모든 스레드를 무료로 닫으십시오.

나는 장벽 지점에 도착하기 위해 더 많은 스레드가 있다고 프로그램이 생각하는지 여부에 관계없이 대기중인 모든 스레드를 해제 할 수있는 방법을 작성하려고합니다.

내 프로그램은

public volatile int count; 
public static boolean cycle = false; 

public static Lock lock = new ReentrantLock(); 
public static Condition cv = lock.newCondition(); 

public void barrier() throws InterruptedException { 
    boolean cycle; 
    System.out.println("lock"); 
    lock.lock(); 
    try { 
     cycle = this.cycle; 
     if (--this.count == 0) { 
      System.out.println("releasing all threads"); 
      this.cycle = !this.cycle; 
      cv.signalAll(); 
     } else { 
      while (cycle == this.cycle) { 
       System.out.println("waiting at barrier"); 
       cv.await(); // Line 20 
      } 
     } 
    } finally { 
     System.out.println("unlock"); 
     lock.unlock(); 
    } 
} 

은 내가 단순히 signalAll() 메서드를 호출하고 모든 스레드가없는 것입니다 방법을 만들 수 있습니다 생각, 모든 스레드를 기다리는. 그러나 문제는 프로그램이 더 많은 스레드를 기다리고 있다면 20 행을 대기하기 때문에 잠금을 유지한다는 것입니다.

이 잠금을 해결할 방법이 있습니까? 이 문제에 어떻게 접근해야합니까?

+0

'this.cycle = this.cycle; cv.signalAll();'? – immibis

+0

재사용이 가능한 장벽이라면 freeAll 호출 후에 도착하는 스레드에서 어떤 일이 일어나야하는지 결정해야하며 freeAll은 this.count를 재설정해야합니다. – immibis

답변

0

더 나은 아이디어 - 표준 java.util.concurrent의 기본 사용 - '리셋'방법으로 CyclicBarrier를!

/** 
* Resets the barrier to its initial state. If any parties are 
* currently waiting at the barrier, they will return with a 
* {@link BrokenBarrierException}. Note that resets <em>after</em> 
* a breakage has occurred for other reasons can be complicated to 
* carry out; threads need to re-synchronize in some other way, 
* and choose one to perform the reset. It may be preferable to 
* instead create a new barrier for subsequent use. 
*/ 
public void reset()