2. Monitors

Concurrency
This commit is contained in:
Karsten Jeppesen
2020-08-26 14:25:02 +02:00
parent 6ef88709bb
commit 3196804d11
12 changed files with 250 additions and 0 deletions

6
MonitorCase2/.classpath Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

17
MonitorCase2/.project Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>MonitorCase2</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View 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
View 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();
}
}

View 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();
}
}
}