2. Monitors
Concurrency
This commit is contained in:
40
MonitorCase2/src/Buffer.java
Normal file
40
MonitorCase2/src/Buffer.java
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
public class Buffer {
|
||||
private char[] buffer;
|
||||
private int count = 0, in = 0, out = 0;
|
||||
|
||||
Buffer(int size) {
|
||||
buffer = new char[size];
|
||||
}
|
||||
|
||||
public synchronized void Put(char c) {
|
||||
while (count == buffer.length) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
System.out.println("Producing " + c + " ...");
|
||||
buffer[in] = c;
|
||||
in = (in + 1) % buffer.length;
|
||||
count++;
|
||||
notify();
|
||||
}
|
||||
|
||||
public synchronized char Get() {
|
||||
while (count == 0) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
char c = buffer[out];
|
||||
out = (out + 1) % buffer.length;
|
||||
count--;
|
||||
System.out.println("Consuming " + c + " ...");
|
||||
notify();
|
||||
return c;
|
||||
}
|
||||
}
|
||||
41
MonitorCase2/src/PC.java
Normal file
41
MonitorCase2/src/PC.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* In MonitorCase1, the producer thread quickly fills the buffer
|
||||
* with characters and then waits for the consumer to consume
|
||||
* some characters from the buffer. The problem is that the
|
||||
* producer waits inside the monitor associated with the buffer,
|
||||
* preventing the consumer to execute the synchronized Get
|
||||
* method on the buffer.
|
||||
*
|
||||
* We really want the Producer to release the monitor if the
|
||||
* buffer becomes full and allow the Consumer to proceed.
|
||||
* Similarly, the Consumer must release the monitor if the
|
||||
* buffer becomes empty and allow the Producer to proceed.
|
||||
* To coordinate the two threads, we must use the Object's
|
||||
* wait() and notify or notifyAll() methods.
|
||||
*
|
||||
* The wait() method suspends the calling thread and temporarily
|
||||
* releases ownership of the monitor (so it allows other threads
|
||||
* to acquire the monitor). The suspended thread that called
|
||||
* wait() wakes up only when another thread calls notify() or
|
||||
* notifyAll() on that object.
|
||||
*
|
||||
* The notifyAll() method wakes up all threads waiting on the
|
||||
* object in question. The awakened threads compete for the
|
||||
* monitor. One thread gets it, and the others go back to
|
||||
* waiting.
|
||||
|
||||
*
|
||||
* Code courtesy of www.csc.villanova.edu/~mdamian/threads/javamonitors.html
|
||||
*/
|
||||
public class PC {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Buffer b = new Buffer(4);
|
||||
Producer p = new Producer(b);
|
||||
Consumer c = new Consumer(b);
|
||||
|
||||
p.start();
|
||||
c.start();
|
||||
}
|
||||
|
||||
}
|
||||
27
MonitorCase2/src/ProCon.java
Normal file
27
MonitorCase2/src/ProCon.java
Normal file
@@ -0,0 +1,27 @@
|
||||
class Producer extends Thread {
|
||||
private Buffer buffer;
|
||||
|
||||
Producer(Buffer b) {
|
||||
buffer = b;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
buffer.Put((char) ('A' + i % 26));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Consumer extends Thread {
|
||||
private Buffer buffer;
|
||||
|
||||
Consumer(Buffer b) {
|
||||
buffer = b;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
buffer.Get();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user