2014-07-07 3 views
0

java에서 semaphores을 사용하여 생산자 및 소비자 문제를 구현하려고합니다. 문제는 내가 두 개의 스레드 (생산자와 소비자)를 시작할 때 소비자가 시작하지 않고 버퍼가 가득차면 생산자가 스스로 블록을 잡을 때이다. 동기 방식으로 작동하는 스레드가 하나만있는 것처럼 보입니다. 따라서, 내가 언급 한 바와 같이, 빈, 완전, 뮤텍스 인 3 개의 세마포어를 사용한다. 다음은 가장 간단한 코드입니다.두 번째 스레드가 생산자 고객 예제에서 시작되지 않음

생산자 클래스;

import java.util.concurrent.Semaphore; 

public class Producer implements Runnable { 

    private Semaphore empty; 
    private Semaphore full; 
    private Semaphore mutex; 

    public Producer(Semaphore empty, Semaphore full, Semaphore mutex) { 

     this.empty = empty; 
     this.full = full; 
     this.mutex = mutex; 
    } 

    @Override 
    public void run() { 

     while (true) { 

      try { 
       empty.acquire(); 
       mutex.acquire(); 
       Thread.sleep(500); 
       System.out.println("Producer producess an element"); 
       mutex.release(); 
       full.release(); 
      } catch (InterruptedException e) { 

       e.printStackTrace(); 
      } 
     } 
    } 
} 

소비자 클래스;

import java.util.concurrent.Semaphore; 

public class Consumer implements Runnable { 

    private Semaphore empty; 
    private Semaphore full; 
    private Semaphore mutex; 

    public Consumer(Semaphore empty, Semaphore full, Semaphore mutex) { 

     this.empty = empty; 
     this.full = full; 
     this.mutex = mutex; 
    } 

    @Override 
    public void run() { 

     while (true) { 

      try { 
       full.acquire(); 
       mutex.acquire(); 
       Thread.sleep(500); 
       System.out.println("Consumer consumes an element"); 
       mutex.release(); 
       empty.release(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

ProducerConsumerExample 클래스

import java.util.concurrent.Semaphore; 

public class ProducerConsumerProblem { 

    private Semaphore empty; 
    private Semaphore full; 
    private Semaphore mutex; 

    public ProducerConsumerProblem(int empty, int full) { 

     this.empty = new Semaphore(empty); 
     this.full = new Semaphore(full); 
     this.mutex = new Semaphore(1); 

    } 

    public void runProducerConsumerExample() { 

     Producer producer = new Producer(empty, full, mutex); 
     Consumer consumer = new Consumer(empty, full, mutex); 

     Thread p = new Thread(producer); 
     Thread c = new Thread(consumer); 

     p.run(); 
     c.run(); 
    } 
} 

그리고 마지막으로 테스트 클래스

import org.junit.Before; 
import org.junit.Test; 

public class ProducerConsumerProblemTest { 

    private ProducerConsumerProblem testClass; 
    private static final int  EMPTY = 10; 
    private static final int  FULL = 0; 

    @Before 
    public void setUp() { 

     testClass = new ProducerConsumerProblem(EMPTY, FULL); 
    } 

    @Test 
    public void testName() { 

     testClass.runProducerConsumerExample(); 
    } 
} 

출력 :

Producer producess an element 
Producer producess an element 
Producer producess an element 
Producer producess an element 
Producer producess an element 
Producer producess an element 
Producer producess an element 
Producer producess an element 
Producer producess an element 
Producer producess an element 

10 후 항목은 아무것도 생성되지 발생 및 스레드가 차단됩니다. run()를 사용하지 마십시오

답변

2

는 실행의 새 스레드를 생성하지 않습니다 run()를 호출

p.start(); 
    c.start(); 

해야

p.run(); 
    c.run(); 

start()를 사용합니다. 현재 실행 스레드 내에서 기능을 실행하기 만합니다.

자세한 내용은 this question/answer을 참조하십시오.

테스트 실행이 끝나면 스레드를 올바르게 종료합니다. 그렇지 않으면 테스트를 추가/실행할 때 여러 스레드가 생성됩니다. 스레드를 중단 시키거나 루프가 완료되어야 함을 나타내는 휘발성 부울 값을 설정하십시오.

+0

재미있는 점은 시작을 사용하면 아무 일도 일어나지 않는다는 것입니다. 심지어 제작자가 시작하지 않아서 왜 그런지 묻지 않습니까? :) – quartaela

+0

@quartaela junit이 스패너를 작동시킬 수도 있지만 start를 사용하면 완벽하게 작동합니다. 결코 종료되지 않으므로 스레드 조인조차 도움이되지 않습니다. – laune

+0

나는 문제를 알아 냈다고 생각해. 내가 메인 메소드 내에서 동일한 코드를 사용하면 매력처럼 작동합니다. 그러나 왜 junit이 문제를 일으키는 지 모릅니다. 도와 주셔서 감사합니다. 나는 당신의 대답을 받아 들일 것입니다. – quartaela

관련 문제