diff --git a/u05-4/Semaphore.java b/u05-4/Semaphore.java new file mode 100644 index 0000000..8bd84e5 --- /dev/null +++ b/u05-4/Semaphore.java @@ -0,0 +1,19 @@ +class Semaphore { + private int value; + + public Semaphore(int value) { + this.value = value; + } + + synchronized public void acquire() throws InterruptedException { + while (this.value <= 0) { + wait(); + } + this.value--; + } + + synchronized public void release() { + this.value++; + notify(); + } +} \ No newline at end of file diff --git a/u05-4/WorkQueue.java b/u05-4/WorkQueue.java new file mode 100644 index 0000000..0f37af7 --- /dev/null +++ b/u05-4/WorkQueue.java @@ -0,0 +1,95 @@ +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; + + public WorkQueue(int maxSize) { + readSemaphore = new Semaphore(0); + writeSemaphore = new Semaphore(maxSize); + } + + public void producer() throws InterruptedException { + writeSemaphore.acquire(); + + Task t = new Task(); + tasks.add(t); + + readSemaphore.release(); + } + + public void consumer() throws InterruptedException { + + Task t; + + readSemaphore.acquire(); + + // for some reason, consumer can get here without tasks in the list. how to fix? + System.out.println(tasks.size()); + 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; + } + + 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[5]; + Thread[] consumers = new Thread[5]; + for (int i = 1; i <= 2; i++) { + final int i_final = i; + producers[i] = new Thread(() -> { + try { + for (int j = 0; j < 10; j++) { + w.producer(); + System.out.println("Producer " + i_final + " produced task " + j); + w.printTaksSize(); + // Thread.sleep(100); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }); + consumers[i] = new Thread(() -> { + try { + for (int j = 0; j < 10; j++) { + w.consumer(); + w.printTaksSize(); + System.out.println("Consumer " + i_final + " consumed task " + j); + // 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"); + } +} \ No newline at end of file