2013-06-08 1 views
1

나는 스레드에 대해 더 많이 배우려고 노력 중이며 생산자/소비자 문제에 대한 해결책을 찾는 것이 좋은 출발이라고 생각합니다. 솔루션에 대한 제약 조건 중 하나는 소비자가 생산자가 얼마만큼 생산하는지 미리 알 수 없다는 것입니다. 코드가 예상대로 실행되고 여러 번 실행했지만 결함이 없음을 의미하지는 않습니다. 이 솔루션에 문제가 있습니까?내 생산자/소비자 솔루션이 맞습니까?

package Multithreading.ProducerConsumer; 

import java.util.LinkedList; 
import java.util.concurrent.Semaphore; 

public class ProducerConsumer 
{ 
    private class Producer implements Runnable 
    { 
     @Override 
     public void run() 
     { 
      for(int i = 0; i < 1000; i++) 
      { 
       try 
       { 
        canProduce.acquire(); 
        mutex.acquire(); 
        queue.add(i); 
        mutex.release(); 
        canConsume.release(); 
       } 
       catch (InterruptedException ex) 
       { 
        ; 
       } 
      } 
      try 
      { 
       canConsume.acquire(); 
       isTryingToFinish = true; 
       canConsume.release(); 
      } 
      catch (InterruptedException ex) 
      { 
       ; 
      } 
     } 
    } 

    private class Consumer implements Runnable 
    { 
     @Override 
     public void run() 
     { 
      while(!isDone) 
      { 
       try 
       { 
        canConsume.acquire(); 
        mutex.acquire(); 
        System.out.println(queue.pop()); 
        if(isTryingToFinish && queue.isEmpty()) 
        { 
         isDone = true; 
        } 
        mutex.release(); 
        canProduce.release(); 
       } 
       catch (InterruptedException ex) 
       { 
        ; 
       } 
      } 
     } 
    } 

    Semaphore canProduce; 
    Semaphore canConsume; 
    Semaphore mutex; 
    boolean isTryingToFinish = false; 
    boolean isDone = false; 
    final static int bufferSize = 100; 
    LinkedList<Integer> queue; 

    public ProducerConsumer() 
    { 
     queue = new LinkedList<>(); 
     canProduce = new Semaphore(bufferSize); 
     canConsume = new Semaphore(0); 
     mutex = new Semaphore(1); 
    } 

    public void Go() throws InterruptedException 
    { 
     Thread p = new Thread(new Producer()); 
     Thread c = new Thread(new Consumer()); 
     p.start(); 
     c.start(); 
     p.join(); 
     c.join(); 
     System.out.println("Job Complete!"); 
    } 

    public static void main(String[] args) throws InterruptedException 
    { 
     ProducerConsumer p = new ProducerConsumer(); 
     p.Go(); 
    } 
} 
+0

'try' 블록 전에 mutex/locks/etc를 얻어야하고'finally' 블록에서 역순으로 !!) !! – fge

+0

또한, 당신의'부울'은 최소한 휘발성이 있어야합니다. – fge

답변