2017-01-20 2 views
2
public class semaphoreTest { 

static LinkedList<Integer> integerLinkedList = new LinkedList<>(); 
static Semaphore semaphore = new Semaphore(1); 
static Object lock = new Object(); 

public static void main(String[] args) throws InterruptedException { 
    Thread t1 = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       produce(); 
      } catch (InterruptedException e) { 
      } 
     } 
    }); 

    Thread t2 = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       consume(); 
      } catch (InterruptedException e) { 
      } 
     } 
    }); 

    t1.start(); 
    t2.start(); 

    t1.join(); 
    t2.join(); 

} 


private static void produce() throws InterruptedException { 
    semaphore.acquire(); 
    int value = 0; 
    while (true) { 
     while (integerLinkedList.size() == 10) { 
      semaphore.release(); 
     } 

     integerLinkedList.add(value++); 


    } 

} 

private static void consume() throws InterruptedException { 
    semaphore.acquire(); 
    while (true) { 
     while (integerLinkedList.size() == 0) { 
      semaphore.release(); 
     } 
     //semaphore.release(); 
     Integer value = integerLinkedList.removeFirst(); 
     System.out.println("Size of the List is " + integerLinkedList.size() + " and value removed is " + value); 
     semaphore.release(); 

     Thread.sleep(100); 
    } 
} 


} 

이것은 제작자가 문제로 삼아 세마포어를 잠금으로 쓰려고합니다. 하지만 대략 240 개의 요소를 제거한 후에는 오류 메시지가 Maximum permit count exceeded으로 나타납니다.최대 허용 개수 초과 : 세마포어

나는 올바른 위치에 자물쇠를 풀고 있지만, 그 부분을 획득 할 때 잘못된 점을 알아낼 수는 없습니다. 다음과 같이

오류 메시지는 다음과 같습니다

Exception in thread "Thread-0" java.lang.Error: Maximum permit count exceeded 
at java.util.concurrent.Semaphore$Sync.tryReleaseShared(Semaphore.java:192) 
at java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(AbstractQueuedSynchronizer.java:1341) 
at java.util.concurrent.Semaphore.release(Semaphore.java:426) 
at interviewQuestions.semaphoreTest.procude(semaphoreTest.java:53) 
at interviewQuestions.semaphoreTest.access$000(semaphoreTest.java:12) 
at interviewQuestions.semaphoreTest$1.run(semaphoreTest.java:23) 
at java.lang.Thread.run(Thread.java:745) 
Exception in thread "Thread-1" java.lang.Error: Maximum permit count exceeded 
at java.util.concurrent.Semaphore$Sync.tryReleaseShared(Semaphore.java:192) 
at java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(AbstractQueuedSynchronizer.java:1341) 
at java.util.concurrent.Semaphore.release(Semaphore.java:426) 
at interviewQuestions.semaphoreTest.consume(semaphoreTest.java:72) 
at interviewQuestions.semaphoreTest.access$100(semaphoreTest.java:12) 
at interviewQuestions.semaphoreTest$2.run(semaphoreTest.java:33) 
at java.lang.Thread.run(Thread.java:745) 

답변

0

@Supun 대답은 정확하지만 무한정 실행하려면 스레드가 필요했지만. 그래서 나는 해결책을 찾아 냈다.

public void produces() throws InterruptedException { 

    int value = 0; 
    while (true){ 
     semaphore.acquire(); 
     if(integerList.size() != 10) { 
      integerList.add(value++); 
     } 
     semaphore.release(); 
    } 

} 

public void consumes() throws InterruptedException { 
    Thread.sleep(100); 
    semaphore.acquire(); 
    while (true){ 
     Integer take = integerList.removeFirst(); 
     System.out.println("Size of the BlockingQueue is : "+ integerList.size()+" and the value consumed is :"+take); 
     Thread.sleep(100); 
     semaphore.release(); 
    } 
} 
+0

안녕하세요, 실제로 내 솔루션이 무한히 실행됩니다. 나는 내가 잠시 쉬었다고 약간의 실수를했다. 계속하는 대신에; . 당신은 무한히 달릴 때가있는 동안 (사실) 볼 수 있습니다. :)) 나는 매우 간단하기 때문에 당신의 produce() 메소드를 좋아합니다. 하지만 당신의 consume() 메소드는 잘못된 것으로 보인다. –

5

문제는를 인수보다 당신이 당신의 세마포어 번 이상 릴리스입니다. 세마포어를 해제하려면 while을 제거해야합니다. 한 번만 출시해야하므로 대신 if을 사용하십시오.

귀하의 프로그램에 따라 produce()consume()이로 변경해야합니다.

생산()

private static void produce() throws InterruptedException {  
    int value = 0;  

    while (true) { 
     //try to get control & put an item. 
     semaphore.acquire(); 

     //but if the queue is full, give up and try again. 
     if (integerLinkedList.size() == 10) { 
      semaphore.release(); 
      continue; 
     } 

     //if not full, put an item & release the control. 
     integerLinkedList.add(value++); 
     semaphore.release(); 

    } 

} 

은 (소비)

private static void consume() throws InterruptedException {   
    while (true) { 
     //try to get the control and consume an item. 
     semaphore.acquire(); 

     //but if the queue is empty, give up and try again. 
     if (integerLinkedList.size() == 0) { 
      semaphore.release(); 
      continue; 
     } 

     //if not empty, *consume first one, *print it, *release the control and go sleep. 
     Integer value = integerLinkedList.removeFirst(); 
     System.out.println("Size of the List is " + integerLinkedList.size() + " and value removed is " + value); 

     semaphore.release();  
     Thread.sleep(100); 
    } 
} 

더 안전 측면에있을하고자하는 경우 각 전에 Thread.sleep(50); 같은 어떤 것을 넣을 수 있습니다 break; 문을 사용하면 스레드가 실행을 계속합니다.

나는 전형적인 생산자 소비자 문제를 프로그램한다고 생각했습니다. 내가 뭔가를 바꾸길 원한다면 알려주세요. 어쨌든이게 당신의 기본적인 문제를 해결하기를 바랍니다. :))