import java.util.LinkedList; import java.util.NoSuchElementException; import java.util.Queue; import java.util.concurrent.Semaphore; class WorkQueue { private 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 { Task t; readSemaphore.acquire(); generalAccessSemaphore.acquire(); // for some reason, consumer can get here without tasks in the list. how to fix? // -> adding general access semaphore fixed it :) if (tasks.isEmpty()) { // SHOULD never be reached System.out.println("!!! No tasks in the queue"); return; } try { t = tasks.remove(); } catch (NoSuchElementException e) { System.out.println("!!! No taks in queue (BUT STILL TRIED ACCESSING)"); return; } finally { generalAccessSemaphore.release(); } writeSemaphore.release(); t.run(); } public void printTaksSize() { System.out.println("Tasks in queue: " + tasks.size()); } public static void main(String[] args) { WorkQueue w = new WorkQueue(10); 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 < 100; j++) { w.producer(); w.printTaksSize(); Thread.sleep(100); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); consumers[i] = new Thread(() -> { try { for (int j = 0; j < 100; j++) { w.consumer(); w.printTaksSize(); Thread.sleep(100); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); producers[i].start(); consumers[i].start(); } } } class Task implements Runnable{ public void run() { // System.out.println("Task is running"); } }