diff --git a/u05-4/WorkQueue.java b/u05-4/WorkQueue.java index 0f37af7..3377f72 100644 --- a/u05-4/WorkQueue.java +++ b/u05-4/WorkQueue.java @@ -4,22 +4,26 @@ import java.util.Queue; import java.util.concurrent.Semaphore; class WorkQueue { - private Queue tasks = new LinkedList(); + private volatile Queue tasks = new LinkedList(); private Semaphore readSemaphore; private Semaphore writeSemaphore; + private Semaphore generalAccessSemaphore; public WorkQueue(int maxSize) { readSemaphore = new Semaphore(0); writeSemaphore = new Semaphore(maxSize); + generalAccessSemaphore = new Semaphore(1); } public void producer() throws InterruptedException { writeSemaphore.acquire(); + generalAccessSemaphore.acquire(); Task t = new Task(); tasks.add(t); readSemaphore.release(); + generalAccessSemaphore.release(); } public void consumer() throws InterruptedException { @@ -27,9 +31,10 @@ class WorkQueue { Task t; readSemaphore.acquire(); + generalAccessSemaphore.acquire(); // for some reason, consumer can get here without tasks in the list. how to fix? - System.out.println(tasks.size()); + // -> adding general access semaphore fixed it :) if (tasks.isEmpty()) { // SHOULD never be reached System.out.println("!!! No tasks in the queue"); @@ -43,6 +48,7 @@ class WorkQueue { } writeSemaphore.release(); + generalAccessSemaphore.release(); t.run(); } @@ -54,17 +60,15 @@ class WorkQueue { public static void main(String[] args) { WorkQueue w = new WorkQueue(10); - Thread[] producers = new Thread[5]; - Thread[] consumers = new Thread[5]; - for (int i = 1; i <= 2; i++) { - final int i_final = i; + Thread[] producers = new Thread[50]; + Thread[] consumers = new Thread[50]; + for (int i = 0; i < 50; i++) { producers[i] = new Thread(() -> { try { - for (int j = 0; j < 10; j++) { + for (int j = 0; j < 100; j++) { w.producer(); - System.out.println("Producer " + i_final + " produced task " + j); w.printTaksSize(); - // Thread.sleep(100); + Thread.sleep(100); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); @@ -72,11 +76,10 @@ class WorkQueue { }); consumers[i] = new Thread(() -> { try { - for (int j = 0; j < 10; j++) { + for (int j = 0; j < 100; j++) { w.consumer(); w.printTaksSize(); - System.out.println("Consumer " + i_final + " consumed task " + j); - // Thread.sleep(100); + Thread.sleep(100); } } catch (InterruptedException e) { Thread.currentThread().interrupt();