簡體   English   中英

超過最大許可數量:信號燈

[英]Maximum permit count exceeded : Semaphore

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)

問題是您釋放信號量的次數多於獲得信號量的次數 您應該在刪除的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;之前break; 語句,以便您有時間給其他線程繼續執行。

我假定您編寫了典型的生產者消費者問題。 如果您要我更改某些內容,請告訴我。 無論如何希望這能解決您的基本問題。 :))

盡管@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();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM