2013-05-24 2 views
2

저는 이틀 동안이 문제를 해결하기 위해 노력해 왔습니다. 마침내 포기합니다. 제가 동료 인 사람이 제가 누락 된 것을 제공 할 수 있기를 희망하며 코드를 게시하고 있습니다. 왜냐하면 내가 가까이에 있다고 생각하기 때문입니다. , 도와주세요! 이발사를 들어잠자는 이발사, 세마포어?

코드 : 고객에 대한

public Semaphore customer = new Semaphore(0); 
public Semaphore barber = new Semaphore(0); 
public Semaphore accessSeats = new Semaphore(1); 
public int freeChairs = 5; 

@Override 
public void run() { 
    while (true) { 
     try { 
      customer.acquire(); //it seems the barber never acuires a customer, even after the semaphore is released 
      accessSeats.acquire(); 
      freeChairs += 1; 
      cutHair(); 
      barber.release(); 
      accessSeats.release(); 
     } catch (InterruptedException ex){} 

코드 :

public void run() { 
    while (notCut) { 
     try { 
      bs.accessSeats.acquire(); 
     } catch (InterruptedException ex) {} 
     if (bs.freeChairs > 0) { 
      bs.freeChairs -= 1; 
      bs.customer.release(); 
      bs.accessSeats.release(); 
      try { 
       bs.barber.acquire(); //the customer cant get past this line 
       getHaircut(); 
      } catch (InterruptedException ex) {} 
     } else { 
      bs.accessSeats.release(); 
      notCut = false; 
     } 
    } 
} 

나는 임의의 타이머 1 이발사 100 개 고객을 만들 수 있습니다.

편집 : cutHair() 이발사를 1-5 초 동안 자고 있습니다 (무작위). getHaircut()은 단지 메시지를 출력하고 세트를 설정합니다. notCut=false;

+0

예외가 표시됩니까? 당신이 예외를 잡는 것 같아. 최소한 스택 추적을 인쇄하십시오. –

+0

코드를 읽기 쉽게 만들고 싶었 기 때문에 인쇄했지만 제거했습니다. –

+0

cutHair() 및 getHaircut() 메서드는 무엇을합니까? InterruptedException을 throw하는 것이 있습니까? –

답변

0

Semaphore은 카운팅 세마포어입니다. 자세한 정보는 javadoc을 읽어야합니다. 문제는 barberSemaphoreBarber이 있다는 것을 결코 알리지 못한다는 것입니다. 따라서 Customer을 획득 할 수 없습니다.

해결 방법 : (! 그동안 루프 전에) 당신이 Barber을 만들 때 , 당신이 할 첫번째 일은 barber.release() 전화 또는 1 개 허가를 barber를 초기화하는 것입니다.

0

이 적절한 대답이 아니라 잘못된 것은 이쪽을 봐 몇 가지가 있습니다 :

1) freeChairs는 AtomicInteger되어야한다.

2) 잘못된 블록에서 notCut = false로 설정 한 것 같습니다. getHaircut()을 설정해야합니다. boolean 'cut'이라는 이름을 붙이고 false로 초기화 해보십시오. 이중 음수를 사용하면 사람이 처리하기가 더 어려워집니다!) 3) 세마포어 모음 및 릴리스는 서로에 대해 원자 적이어야하지만 그렇지 않습니다. . 다른 스레드가 이발 세마포어가 해제 된 상태를 볼 수해서는 안하지만 accessSeats는하지 않았지만이 여기에 사실이 아니다 - 그것은 원자해야처럼 예를 들어

barber.release(); 
accessSeats.release(); 

보인다. 다른 세마포어에서 요청/릴리스를 호출하는 순서에 매우주의하지 않는 한 교착 상태가 발생할 수 있습니다.