2017-01-20 9 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(); 

    } 

} 

あなたはより安全な側になりたい場合は、それぞれの前にThread.sleep(50);のようないくつかのことを置くことができる)(

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); 
    } 
} 

を消費break;ステートメントは、そのスレッドは実行を続行します。

一般的なプロデューサのコンシューマの問題をプログラムすると仮定しました。私に何かを変えさせたいなら、私に知らせてください。とにかく、これはあなたの基本的な問題を並べ替えることを願っています:))

関連する問題