2017-01-20 4 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

Привет, На самом деле мое решение работает бесконечно. Я сделал небольшую ошибку, которую я назвал перерывом; вместо продолжения; , Вы можете видеть, что while (true) существует, который должен работать бесконечно. :)) Мне нравится ваш метод product(), поскольку он очень прост. но ваш метод потребления() кажется неправильным. –

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;, так что вы даете некоторое время для o чтобы продолжить его выполнение.

Я предполагал, что вы программируете типичную проблему с потребителем-производителем. Если вы хотите, чтобы я что-то изменил, пожалуйста, дайте мне знать. В любом случае, надеюсь, что это избавит вас от основной проблемы. :))

Смежные вопросы