Laboraufgaben für Kap. 3

pull/1/head
Sandro Leuchter 2024-10-09 10:48:52 +02:00
parent cdcb0c69fc
commit dff9d7719f
61 changed files with 1673 additions and 631 deletions

View File

@ -1,40 +1,41 @@
package pp; package pp;
public class Sensor extends Thread { public class Sensor extends Thread {
// eigentlich abstract
// eigentlich abstract
private final long frequency;
private final long frequency;
public Sensor(long frequency) {
this.frequency = frequency; public Sensor(long frequency) {
start(); this.frequency = frequency;
} start();
}
/**
* @return the frequency /**
*/ * @return the frequency
public long getFrequency() { */
return this.frequency; public long getFrequency() {
} return this.frequency;
}
protected String reading() {
// eigentlich abstract protected String reading() {
return null; // eigentlich abstract
} return null;
}
@Override
public void run() { @Override
while (true) { public void run() {
System.out.println("reading: " + reading()); while (true) {
try { System.out.println("reading: " + reading());
Thread.sleep(this.frequency); try {
} catch (InterruptedException e) { Thread.sleep(this.frequency);
Thread.currentThread().interrupt(); } catch (InterruptedException e) {
} Thread.currentThread().interrupt();
} }
} }
}
public static void main(String... args) {
var s = new Sensor(1000); public static void main(String... args) {
} var s = new Sensor(1000);
} }
}

View File

@ -1,23 +1,23 @@
package pp; package pp;
import java.util.Random; import java.util.Random;
public class Thermometer extends Sensor { public class Thermometer extends Sensor {
private final Random rand;
private final Random rand;
public Thermometer(long frequency) {
super(frequency); public Thermometer(long frequency) {
this.rand = new Random(); super(frequency);
} this.rand = new Random();
}
@Override
protected String reading() { @Override
return String.format("(%04d freq.): %3d°C", getFrequency(), protected String reading() {
this.rand.nextInt(100)); return String.format("(%04d freq.): %3d°C", getFrequency(), this.rand.nextInt(100));
} }
public static void main(String... args) { public static void main(String... args) {
var s1 = new Thermometer(1000); var s1 = new Thermometer(1000);
var s2 = new Thermometer(3000); var s2 = new Thermometer(3000);
} }
} }

View File

@ -1,40 +1,41 @@
package pp; package pp;
public class Sensor extends Thread { public class Sensor extends Thread {
// eigentlich abstract
// eigentlich abstract
private final long frequency;
private final long frequency;
public Sensor(long frequency) {
this.frequency = frequency; public Sensor(long frequency) {
} this.frequency = frequency;
}
/**
* @return the frequency /**
*/ * @return the frequency
public long getFrequency() { */
return this.frequency; public long getFrequency() {
} return this.frequency;
}
protected String reading() {
// eigentlich abstract protected String reading() {
return null; // eigentlich abstract
} return null;
}
@Override
public void run() { @Override
while (true) { public void run() {
System.out.println("reading: " + reading()); while (true) {
try { System.out.println("reading: " + reading());
Thread.sleep(this.frequency); try {
} catch (InterruptedException e) { Thread.sleep(this.frequency);
Thread.currentThread().interrupt(); } catch (InterruptedException e) {
} Thread.currentThread().interrupt();
} }
} }
}
public static void main(String... args) {
var s = new Sensor(1000); public static void main(String... args) {
s.start(); var s = new Sensor(1000);
} s.start();
} }
}

View File

@ -1,25 +1,25 @@
package pp; package pp;
import java.util.Random; import java.util.Random;
public class Thermometer extends Sensor { public class Thermometer extends Sensor {
private final Random rand;
private final Random rand;
public Thermometer(long frequency) {
super(frequency); public Thermometer(long frequency) {
this.rand = new Random(); super(frequency);
} this.rand = new Random();
}
@Override
protected String reading() { @Override
return String.format("(%04d freq.): %3d°C", getFrequency(), protected String reading() {
this.rand.nextInt(100)); return String.format("(%04d freq.): %3d°C", getFrequency(), this.rand.nextInt(100));
} }
public static void main(String... args) { public static void main(String... args) {
var s1 = new Thermometer(1000); var s1 = new Thermometer(1000);
s1.start(); s1.start();
var s2 = new Thermometer(3000); var s2 = new Thermometer(3000);
s2.start(); s2.start();
} }
} }

View File

@ -1,14 +1,14 @@
package pp; package pp;
class MyWorker implements Runnable { class MyWorker implements Runnable {
private Thread self;
private Thread self;
@Override
public void run() { @Override
this.self = Thread.currentThread(); public void run() {
while (true) { this.self = Thread.currentThread();
System.out.println( while (true) {
this.self.getName() + ": ID => " + this.self.threadId()); System.out.println(this.self.getName() + ": ID => " + this.self.threadId());
} }
} }
} }

View File

@ -1,15 +1,15 @@
package pp; package pp;
class MyWorkerCoop implements Runnable { class MyWorkerCoop implements Runnable {
private Thread self;
private Thread self;
@Override
public void run() { @Override
this.self = Thread.currentThread(); public void run() {
while (true) { this.self = Thread.currentThread();
System.out.println( while (true) {
this.self.getName() + ": ID => " + this.self.threadId()); System.out.println(this.self.getName() + ": ID => " + this.self.threadId());
Thread.yield(); Thread.yield();
} }
} }
} }

View File

@ -1,12 +1,13 @@
package pp; package pp;
public class Starter { public class Starter {
static int WORKERS = 200;
static int WORKERS = 200;
public static void main(String... args) {
for (var i = 0; i < Starter.WORKERS; i++) { public static void main(String... args) {
var t = new Thread(new MyWorker(), String.format("Worker-%03d", i)); for (var i = 0; i < Starter.WORKERS; i++) {
t.start(); var t = new Thread(new MyWorker(), String.format("Worker-%03d", i));
} t.start();
} }
} }
}

View File

@ -1,14 +1,14 @@
package pp; package pp;
class MyWorker implements Runnable { class MyWorker implements Runnable {
private Thread self;
private Thread self;
@Override
public void run() { @Override
this.self = Thread.currentThread(); public void run() {
while (true) { this.self = Thread.currentThread();
System.out.println( while (true) {
this.self.getName() + ": ID => " + this.self.threadId()); System.out.println(this.self.getName() + ": ID => " + this.self.threadId());
} }
} }
} }

View File

@ -1,15 +1,15 @@
package pp; package pp;
class MyWorkerCoop implements Runnable { class MyWorkerCoop implements Runnable {
private Thread self;
private Thread self;
@Override
public void run() { @Override
this.self = Thread.currentThread(); public void run() {
while (true) { this.self = Thread.currentThread();
System.out.println( while (true) {
this.self.getName() + ": ID => " + this.self.threadId()); System.out.println(this.self.getName() + ": ID => " + this.self.threadId());
Thread.yield(); Thread.yield();
} }
} }
} }

View File

@ -1,13 +1,13 @@
package pp; package pp;
public class Starter { public class Starter {
static int WORKERS = 200;
static int WORKERS = 200;
public static void main(String... args) {
for (var i = 0; i < Starter.WORKERS; i++) { public static void main(String... args) {
var t = new Thread(new MyWorkerCoop(), for (var i = 0; i < Starter.WORKERS; i++) {
String.format("Worker-%03d", i)); var t = new Thread(new MyWorkerCoop(), String.format("Worker-%03d", i));
t.start(); t.start();
} }
} }
} }

View File

@ -1,23 +1,26 @@
package pp; package pp;
public class StarterInner { public class StarterInner {
static int WORKERS = 200;
static int WORKERS = 200;
public static void main(String... args) {
for (var i = 0; i < StarterInner.WORKERS; i++) { public static void main(String... args) {
var t = new Thread(new Runnable() { for (var i = 0; i < StarterInner.WORKERS; i++) {
private Thread self; var t = new Thread(
new Runnable() {
@Override private Thread self;
public void run() {
this.self = Thread.currentThread(); @Override
while (true) { public void run() {
System.out.println(this.self.getName() + ": ID => " this.self = Thread.currentThread();
+ this.self.threadId()); while (true) {
} System.out.println(this.self.getName() + ": ID => " + this.self.threadId());
} }
}, String.format("Worker-%03d", i)); }
t.start(); },
} String.format("Worker-%03d", i)
} );
} t.start();
}
}
}

View File

@ -1,18 +1,21 @@
package pp; package pp;
public class StarterLambda { public class StarterLambda {
static int WORKERS = 200;
static int WORKERS = 200;
public static void main(String... args) {
for (var i = 0; i < StarterLambda.WORKERS; i++) { public static void main(String... args) {
var t = new Thread(() -> { for (var i = 0; i < StarterLambda.WORKERS; i++) {
var self = Thread.currentThread(); var t = new Thread(
while (true) { () -> {
System.out.println( var self = Thread.currentThread();
self.getName() + ": ID => " + self.threadId()); while (true) {
} System.out.println(self.getName() + ": ID => " + self.threadId());
}, String.format("Worker-%03d", i)); }
t.start(); },
} String.format("Worker-%03d", i)
} );
} t.start();
}
}
}

View File

@ -1,15 +1,16 @@
package pp; package pp;
public class Runner { public class Runner {
public static void main(String... args) {
var task = new Task(); public static void main(String... args) {
var thread = new Thread(task); var task = new Task();
thread.setUncaughtExceptionHandler((t, e) -> { var thread = new Thread(task);
System.err.println("Unhandled Exception: " + e.getMessage()); thread.setUncaughtExceptionHandler((t, e) -> {
System.err.println(" Thread: " + t.threadId() + " - " + t.getName()); System.err.println("Unhandled Exception: " + e.getMessage());
System.err.println(" Thread State: " + t.getState()); System.err.println(" Thread: " + t.threadId() + " - " + t.getName());
e.printStackTrace(System.err); System.err.println(" Thread State: " + t.getState());
}); e.printStackTrace(System.err);
thread.start(); });
} thread.start();
} }
}

View File

@ -1,35 +1,36 @@
package pp; package pp;
public class Task implements Runnable { public class Task implements Runnable {
private volatile Thread self;
private volatile boolean stopped = false; private volatile Thread self;
private volatile boolean stopped = false;
public void stopRequest() {
this.stopped = true; public void stopRequest() {
if (this.self != null) { this.stopped = true;
this.self.interrupt(); if (this.self != null) {
} this.self.interrupt();
} }
}
public boolean isStopped() {
return this.stopped; public boolean isStopped() {
} return this.stopped;
}
@Override
public void run() { @Override
this.self = Thread.currentThread(); public void run() {
// 1. Initialisierungsphase this.self = Thread.currentThread();
var i = 10; // 1. Initialisierungsphase
while (!isStopped()) { var i = 10;
// 2. Arbeitsphase while (!isStopped()) {
System.out.println("i=" + i); // 2. Arbeitsphase
try { System.out.println("i=" + i);
Thread.sleep(1000 / i--); try {
} catch (InterruptedException e) { Thread.sleep(1000 / i--);
Thread.currentThread().interrupt(); } catch (InterruptedException e) {
} Thread.currentThread().interrupt();
} }
// 3. Aufräumphase }
System.out.println("fertig."); // 3. Aufräumphase
} System.out.println("fertig.");
} }
}

View File

@ -1,20 +1,21 @@
package pp; package pp;
public class Runner { public class Runner {
public static void main(String... args) {
var task = new Task(); public static void main(String... args) {
var thread = new Thread(task); var task = new Task();
thread.setUncaughtExceptionHandler((t, e) -> { var thread = new Thread(task);
System.err.println("Unhandled Exception: " + e.getMessage()); thread.setUncaughtExceptionHandler((t, e) -> {
System.err.println(" Thread: " + t.threadId() + " - " + t.getName()); System.err.println("Unhandled Exception: " + e.getMessage());
System.err.println(" Thread State: " + t.getState()); System.err.println(" Thread: " + t.threadId() + " - " + t.getName());
e.printStackTrace(System.err); System.err.println(" Thread State: " + t.getState());
}); e.printStackTrace(System.err);
thread.start(); });
// falsch: thread läuft weiter: thread.start();
// (new Thread(() -> thread.interrupt())).start(); // falsch: thread läuft weiter:
// (new Thread(() -> thread.interrupt())).start();
// richtig: thread wird beendet:
(new Thread(() -> task.stopRequest())).start(); // richtig: thread wird beendet:
} (new Thread(() -> task.stopRequest())).start();
} }
}

View File

@ -1,35 +1,36 @@
package pp; package pp;
public class Task implements Runnable { public class Task implements Runnable {
private volatile Thread self;
private volatile boolean stopped = false; private volatile Thread self;
private volatile boolean stopped = false;
public void stopRequest() {
this.stopped = true; public void stopRequest() {
if (this.self != null) { this.stopped = true;
this.self.interrupt(); if (this.self != null) {
} this.self.interrupt();
} }
}
public boolean isStopped() {
return this.stopped; public boolean isStopped() {
} return this.stopped;
}
@Override
public void run() { @Override
this.self = Thread.currentThread(); public void run() {
// 1. Initialisierungsphase this.self = Thread.currentThread();
var i = 10; // 1. Initialisierungsphase
while (!isStopped()) { var i = 10;
// 2. Arbeitsphase while (!isStopped()) {
System.out.println("i=" + i); // 2. Arbeitsphase
try { System.out.println("i=" + i);
Thread.sleep(1000 / i--); try {
} catch (InterruptedException e) { Thread.sleep(1000 / i--);
Thread.currentThread().interrupt(); } catch (InterruptedException e) {
} Thread.currentThread().interrupt();
} }
// 3. Aufräumphase }
System.out.println("fertig."); // 3. Aufräumphase
} System.out.println("fertig.");
} }
}

View File

@ -1,24 +1,22 @@
package pp; package pp;
public class MemoryBarrierTest extends Thread { public class MemoryBarrierTest extends Thread {
public boolean stopped = false; public boolean stopped = false;
@Override @Override
public void run() { public void run() {
while (!this.stopped) { while (!this.stopped) {
// work // work
} }
System.out.println("MemoryBarrierTest-Thread actually stopped."); System.out.println("MemoryBarrierTest-Thread actually stopped.");
} }
public static void main(String... args) throws InterruptedException { public static void main(String... args) throws InterruptedException {
var t = new MemoryBarrierTest(); var t = new MemoryBarrierTest();
t.start(); t.start();
Thread.sleep(1000); Thread.sleep(1000);
t.stopped = true; t.stopped = true;
System.out.println( System.out.println("Main thread set stopped on MemoryBarrierTest-Thread.");
"Main thread set stopped on MemoryBarrierTest-Thread."); }
} }
}

View File

@ -1,26 +1,24 @@
package pp; package pp;
public class MemoryBarrierTest1 extends Thread { public class MemoryBarrierTest1 extends Thread {
// Markierung von stopped als volatile => Jede Änderung wirkt als // Markierung von stopped als volatile => Jede Änderung wirkt als
// Memory-Barrier // Memory-Barrier
public volatile boolean stopped = false; public volatile boolean stopped = false;
@Override @Override
public void run() { public void run() {
while (!this.stopped) { while (!this.stopped) {
// work // work
} }
System.out.println("MemoryBarrierTest-Thread actually stopped."); System.out.println("MemoryBarrierTest-Thread actually stopped.");
} }
public static void main(String... args) throws InterruptedException { public static void main(String... args) throws InterruptedException {
var t = new MemoryBarrierTest1(); var t = new MemoryBarrierTest1();
t.start(); t.start();
Thread.sleep(1000); Thread.sleep(1000);
t.stopped = true; t.stopped = true;
System.out.println( System.out.println("Main thread set stopped on MemoryBarrierTest-Thread.");
"Main thread set stopped on MemoryBarrierTest-Thread."); }
} }
}

View File

@ -29,8 +29,6 @@ public class MemoryBarrierTest1b extends Thread {
t.start(); t.start();
Thread.sleep(1000); Thread.sleep(1000);
t.setStopped(true); t.setStopped(true);
System.out.println( System.out.println("Main thread set stopped on MemoryBarrierTest-Thread.");
"Main thread set stopped on MemoryBarrierTest-Thread.");
} }
} }

View File

@ -1,28 +1,26 @@
package pp; package pp;
public class MemoryBarrierTest2 extends Thread { public class MemoryBarrierTest2 extends Thread {
public boolean stopped = false; public boolean stopped = false;
@Override @Override
public void run() { public void run() {
while (!this.stopped) { while (!this.stopped) {
// jedes synchronized wirkt als Memory-Barrier // jedes synchronized wirkt als Memory-Barrier
// work // work
synchronized (this) { synchronized (this) {
// //
} }
} }
System.out.println("MemoryBarrierTest-Thread actually stopped."); System.out.println("MemoryBarrierTest-Thread actually stopped.");
} }
public static void main(String... args) throws InterruptedException { public static void main(String... args) throws InterruptedException {
var t = new MemoryBarrierTest2(); var t = new MemoryBarrierTest2();
t.start(); t.start();
Thread.sleep(1000); Thread.sleep(1000);
t.stopped = true; t.stopped = true;
System.out.println( System.out.println("Main thread set stopped on MemoryBarrierTest-Thread.");
"Main thread set stopped on MemoryBarrierTest-Thread."); }
} }
}

View File

@ -13,8 +13,7 @@ public class MemoryBarrierTest5 extends Thread {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
this.stopped = true; this.stopped = true;
System.out.println( System.out.println("Stopper thread set stopped on MemoryBarrierTest-Thread.");
"Stopper thread set stopped on MemoryBarrierTest-Thread.");
}); });
this.stopper.start(); this.stopper.start();
} }
@ -40,7 +39,5 @@ public class MemoryBarrierTest5 extends Thread {
public static void main(String... args) throws InterruptedException { public static void main(String... args) throws InterruptedException {
var t = new MemoryBarrierTest5(); var t = new MemoryBarrierTest5();
t.start(); t.start();
} }
} }

View File

@ -1,30 +1,28 @@
package pp; package pp;
public class MemoryBarrierTest6 extends Thread { public class MemoryBarrierTest6 extends Thread {
public boolean stopped = false; public boolean stopped = false;
@Override @Override
public void run() { public void run() {
while (!this.stopped) { while (!this.stopped) {
// work // work
// wg. Zustandswechsel // wg. Zustandswechsel
try { try {
Thread.sleep(1); Thread.sleep(1);
} catch (InterruptedException e) { } catch (InterruptedException e) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
} }
System.out.println("MemoryBarrierTest-Thread actually stopped."); System.out.println("MemoryBarrierTest-Thread actually stopped.");
} }
public static void main(String... args) throws InterruptedException { public static void main(String... args) throws InterruptedException {
var t = new MemoryBarrierTest6(); var t = new MemoryBarrierTest6();
t.start(); t.start();
Thread.sleep(1000); Thread.sleep(1000);
t.stopped = true; t.stopped = true;
System.out.println( System.out.println("Main thread set stopped on MemoryBarrierTest-Thread.");
"Main thread set stopped on MemoryBarrierTest-Thread."); }
} }
}

View File

@ -1,25 +1,26 @@
package pp; package pp;
import java.util.Random; import java.util.Random;
public class MyThreadLocalRandom0 implements Runnable { public class MyThreadLocalRandom0 implements Runnable {
public static long now = System.currentTimeMillis();
public Random rand = new Random(now); public static long now = System.currentTimeMillis();
public Random rand = new Random(now);
@Override
public void run() { @Override
var strBuf = new StringBuffer(); public void run() {
strBuf.append(Thread.currentThread().getName() + ": "); var strBuf = new StringBuffer();
for (var j = 0; j < 20; j++) { strBuf.append(Thread.currentThread().getName() + ": ");
strBuf.append(String.format("%02d ", this.rand.nextInt(100))); for (var j = 0; j < 20; j++) {
} strBuf.append(String.format("%02d ", this.rand.nextInt(100)));
System.out.println(strBuf); }
} System.out.println(strBuf);
}
public static void main(String... args) {
var runner = new MyThreadLocalRandom0(); public static void main(String... args) {
for (var i = 0; i < 10; i++) { var runner = new MyThreadLocalRandom0();
new Thread(runner, String.format("Runner-%02d", i)).start(); for (var i = 0; i < 10; i++) {
} new Thread(runner, String.format("Runner-%02d", i)).start();
} }
} }
}

View File

@ -1,30 +1,31 @@
package pp; package pp;
import java.util.Random; import java.util.Random;
public class MyThreadLocalRandom1 implements Runnable { public class MyThreadLocalRandom1 implements Runnable {
public static long now = System.currentTimeMillis();
public ThreadLocal<Random> rand = new ThreadLocal<>() { public static long now = System.currentTimeMillis();
@Override public ThreadLocal<Random> rand = new ThreadLocal<>() {
protected Random initialValue() { @Override
return new Random(now); protected Random initialValue() {
} return new Random(now);
}; }
};
@Override
public void run() { @Override
var strBuf = new StringBuffer(); public void run() {
strBuf.append(Thread.currentThread().getName() + ": "); var strBuf = new StringBuffer();
for (var j = 0; j < 20; j++) { strBuf.append(Thread.currentThread().getName() + ": ");
strBuf.append(String.format("%02d ", this.rand.get().nextInt(100))); for (var j = 0; j < 20; j++) {
} strBuf.append(String.format("%02d ", this.rand.get().nextInt(100)));
System.out.println(strBuf); }
} System.out.println(strBuf);
}
public static void main(String... args) {
var runner = new MyThreadLocalRandom1(); public static void main(String... args) {
for (var i = 0; i < 10; i++) { var runner = new MyThreadLocalRandom1();
new Thread(runner, String.format("Runner-%02d", i)).start(); for (var i = 0; i < 10; i++) {
} new Thread(runner, String.format("Runner-%02d", i)).start();
} }
} }
}

View File

@ -1,30 +1,31 @@
package pp; package pp;
import java.util.Random; import java.util.Random;
public class MyThreadLocalRandom2 implements Runnable { public class MyThreadLocalRandom2 implements Runnable {
public static long now = System.currentTimeMillis();
public static ThreadLocal<Random> rand = new ThreadLocal<>() { public static long now = System.currentTimeMillis();
@Override public static ThreadLocal<Random> rand = new ThreadLocal<>() {
protected Random initialValue() { @Override
return new Random(now); protected Random initialValue() {
} return new Random(now);
}; }
};
@Override
public void run() { @Override
var strBuf = new StringBuffer(); public void run() {
strBuf.append(Thread.currentThread().getName() + ": "); var strBuf = new StringBuffer();
for (var j = 0; j < 20; j++) { strBuf.append(Thread.currentThread().getName() + ": ");
strBuf.append(String.format("%02d ", rand.get().nextInt(100))); for (var j = 0; j < 20; j++) {
} strBuf.append(String.format("%02d ", rand.get().nextInt(100)));
System.out.println(strBuf); }
} System.out.println(strBuf);
}
public static void main(String... args) {
var runner = new MyThreadLocalRandom2(); public static void main(String... args) {
for (var i = 0; i < 10; i++) { var runner = new MyThreadLocalRandom2();
new Thread(runner, String.format("Runner-%02d", i)).start(); for (var i = 0; i < 10; i++) {
} new Thread(runner, String.format("Runner-%02d", i)).start();
} }
} }
}

View File

@ -1,28 +1,28 @@
package pp; package pp;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public class MyThreadLocalRandom3 implements Runnable { public class MyThreadLocalRandom3 implements Runnable {
public static Random rand = ThreadLocalRandom.current(); public static Random rand = ThreadLocalRandom.current();
@Override @Override
public void run() { public void run() {
var strBuf = new StringBuffer(); var strBuf = new StringBuffer();
strBuf.append(Thread.currentThread().getName() + ": "); strBuf.append(Thread.currentThread().getName() + ": ");
for (var j = 0; j < 20; j++) { for (var j = 0; j < 20; j++) {
synchronized (MyThreadLocalRandom3.class) { synchronized (MyThreadLocalRandom3.class) {
strBuf.append(String.format("%02d ", rand.nextInt(100))); strBuf.append(String.format("%02d ", rand.nextInt(100)));
} }
} }
System.out.println(strBuf); System.out.println(strBuf);
} }
public static void main(String... args) throws InterruptedException { public static void main(String... args) throws InterruptedException {
var runner = new MyThreadLocalRandom3(); var runner = new MyThreadLocalRandom3();
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
new Thread(runner, String.format("Runner-%02d", i)).start(); new Thread(runner, String.format("Runner-%02d", i)).start();
} }
} }
} }

View File

@ -1,28 +1,28 @@
package pp; package pp;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public class MyThreadLocalRandom4 implements Runnable { public class MyThreadLocalRandom4 implements Runnable {
public Random rand = ThreadLocalRandom.current(); public Random rand = ThreadLocalRandom.current();
@Override @Override
public void run() { public void run() {
var strBuf = new StringBuffer(); var strBuf = new StringBuffer();
strBuf.append(Thread.currentThread().getName() + ": "); strBuf.append(Thread.currentThread().getName() + ": ");
for (var j = 0; j < 20; j++) { for (var j = 0; j < 20; j++) {
synchronized (MyThreadLocalRandom4.class) { synchronized (MyThreadLocalRandom4.class) {
strBuf.append(String.format("%02d ", this.rand.nextInt(100))); strBuf.append(String.format("%02d ", this.rand.nextInt(100)));
} }
} }
System.out.println(strBuf); System.out.println(strBuf);
} }
public static void main(String... args) throws InterruptedException { public static void main(String... args) throws InterruptedException {
var runner = new MyThreadLocalRandom4(); var runner = new MyThreadLocalRandom4();
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
new Thread(runner, String.format("Runner-%02d", i)).start(); new Thread(runner, String.format("Runner-%02d", i)).start();
} }
} }
} }

View File

@ -21,9 +21,7 @@ public class Factory {
() -> { () -> {
Type object = Factory.getInstance(); Type object = Factory.getInstance();
System.out.println( System.out.println(
Thread.currentThread().getName() + Thread.currentThread().getName() + ": serial of instance = " + object.getSerial()
": serial of instance = " +
object.getSerial()
); );
}, },
String.format("InstanceGrabber-%02d", i) String.format("InstanceGrabber-%02d", i)

View File

@ -20,9 +20,7 @@ public class Factory0 {
() -> { () -> {
var object = getInstance(); var object = getInstance();
System.out.println( System.out.println(
Thread.currentThread().getName() + Thread.currentThread().getName() + ": serial of instance = " + object.getSerial()
": serial of instance = " +
object.getSerial()
); );
}, },
String.format("InstanceGrabber-%02d", i) String.format("InstanceGrabber-%02d", i)

View File

@ -20,9 +20,7 @@ public class Factory1 {
() -> { () -> {
var object = getInstance(); var object = getInstance();
System.out.println( System.out.println(
Thread.currentThread().getName() + Thread.currentThread().getName() + ": serial of instance = " + object.getSerial()
": serial of instance = " +
object.getSerial()
); );
}, },
String.format("InstanceGrabber-%02d", i) String.format("InstanceGrabber-%02d", i)

View File

@ -22,9 +22,7 @@ public class Factory2 {
() -> { () -> {
var object = getInstance(); var object = getInstance();
System.out.println( System.out.println(
Thread.currentThread().getName() + Thread.currentThread().getName() + ": serial of instance = " + object.getSerial()
": serial of instance = " +
object.getSerial()
); );
}, },
String.format("InstanceGrabber-%02d", i) String.format("InstanceGrabber-%02d", i)

View File

@ -23,9 +23,7 @@ public class Factory3 {
() -> { () -> {
var object = Factory3.getInstance(); var object = Factory3.getInstance();
System.out.println( System.out.println(
Thread.currentThread().getName() + Thread.currentThread().getName() + ": serial of instance = " + object.getSerial()
": serial of instance = " +
object.getSerial()
); );
}, },
String.format("InstanceGrabber-%02d", i) String.format("InstanceGrabber-%02d", i)

View File

@ -24,9 +24,7 @@ public class Factory4 {
() -> { () -> {
var object = getInstance(); var object = getInstance();
System.out.println( System.out.println(
Thread.currentThread().getName() + Thread.currentThread().getName() + ": serial of instance = " + object.getSerial()
": serial of instance = " +
object.getSerial()
); );
}, },
String.format("InstanceGrabber-%02d", i) String.format("InstanceGrabber-%02d", i)

View File

@ -0,0 +1,7 @@
# Laboraufgabe "Dinnierende Philosoph:innen"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-01-SynchPhilosopher.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-Solutions.html#laboraufgabe-dinierende-philosophinnen)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/03-steuerung.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/03-steuerung.html)

View File

@ -0,0 +1,12 @@
default:
mvn clean compile exec:java
exec args:
mvn exec:java -Dexec.args={{args}}
clean:
mvn clean
compile:
mvn compile
test:
mvn test
javadoc:
mvn javadoc:javadoc

View File

@ -0,0 +1,61 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pp</groupId>
<artifactId>pp.03.01-SynchPhilosopher</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.PhilosopherExperiment</exec.mainClass>
<maven.compiler.release>19</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency><!-- für Unit-Tests -->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency><!-- für Lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<dependency><!-- für net.jcip Annotationen -->
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin><!-- für Unit-Tests [mvn test] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin><!-- [mvn compile] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
</plugin>
<plugin><!-- [mvn exec:java] -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin><!-- [mvn javadoc:javadoc] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<show>private</show>
<locale>en_US</locale>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,3 @@
package pp;
public class Chopstick {}

View File

@ -0,0 +1,77 @@
package pp;
import java.util.Random;
public class Philosopher extends Thread {
static final int MAX_THINKING_DURATION_MS = 1000;
static final int MAX_EATING_DURATION_MS = 3000;
static final int MAX_TAKING_TIME_MS = 1000;
private final Chopstick left;
private final Chopstick right;
private final Random random;
private int eaten;
private final int seat;
private volatile boolean stop;
private void log(String message) {
synchronized (Philosopher.class) {
for (var i = 1; i <= this.seat; i++) {
System.out.print(" ");
}
System.out.println(threadId() + " " + message);
}
}
public void stopPhilosopher() {
log("stopping");
this.stop = true;
interrupt();
}
public Philosopher(int seat, Chopstick left, Chopstick right) {
this.stop = false;
this.seat = seat;
this.left = left;
this.right = right;
this.random = new Random();
this.eaten = 0;
}
@Override
public void run() {
log("starting");
try {
while (!this.stop) {
think();
eat();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
log("stopped; eaten=" + this.eaten);
}
private void think() throws InterruptedException {
Thread.sleep(this.random.nextInt(MAX_THINKING_DURATION_MS));
}
private void eat() throws InterruptedException {
log("try taking left");
synchronized (this.left) {
log("left acquired");
Thread.sleep(this.random.nextInt(MAX_TAKING_TIME_MS));
log("try taking right");
synchronized (this.right) {
log("right acquired");
log("eating");
this.eaten++;
Thread.sleep(this.random.nextInt(MAX_EATING_DURATION_MS));
}
log("right released");
}
log("left released");
}
}

View File

@ -0,0 +1,25 @@
package pp;
public class PhilosopherExperiment {
static final int PHILOSOPHER_NUM = 5;
static final int EXP_DURATION_MS = 20000;
public static void main(String... args) throws InterruptedException {
var chopsticks = new Chopstick[PHILOSOPHER_NUM];
var philosophers = new Philosopher[PHILOSOPHER_NUM];
for (var i = 0; i < PHILOSOPHER_NUM; i++) {
chopsticks[i] = new Chopstick();
}
for (var i = 0; i < PHILOSOPHER_NUM; i++) {
philosophers[i] = new Philosopher(i, chopsticks[i], chopsticks[(i + 1) % PHILOSOPHER_NUM]);
}
for (var i = 0; i < PHILOSOPHER_NUM; i++) {
philosophers[i].start();
}
Thread.sleep(EXP_DURATION_MS);
for (var i = 0; i < PHILOSOPHER_NUM; i++) {
philosophers[i].stopPhilosopher();
}
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "Dinnierende Philosoph:innen"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-01-SynchPhilosopher.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-Solutions.html#laboraufgabe-dinierende-philosophinnen)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/03-steuerung.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/03-steuerung.html)

View File

@ -0,0 +1,12 @@
default:
mvn clean compile exec:java
exec args:
mvn exec:java -Dexec.args={{args}}
clean:
mvn clean
compile:
mvn compile
test:
mvn test
javadoc:
mvn javadoc:javadoc

View File

@ -0,0 +1,61 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pp</groupId>
<artifactId>pp.03.01-SynchPhilosopher_solution</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.PhilosopherExperiment</exec.mainClass>
<maven.compiler.release>19</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency><!-- für Unit-Tests -->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency><!-- für Lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<dependency><!-- für net.jcip Annotationen -->
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin><!-- für Unit-Tests [mvn test] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin><!-- [mvn compile] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
</plugin>
<plugin><!-- [mvn exec:java] -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin><!-- [mvn javadoc:javadoc] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<show>private</show>
<locale>en_US</locale>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,3 @@
package pp;
public class Chopstick {}

View File

@ -0,0 +1,77 @@
package pp;
import java.util.Random;
public class Philosopher extends Thread {
static final int MAX_THINKING_DURATION_MS = 1000;
static final int MAX_EATING_DURATION_MS = 3000;
static final int MAX_TAKING_TIME_MS = 1000;
private final Chopstick left;
private final Chopstick right;
private final Random random;
private int eaten;
private final int seat;
private volatile boolean stop;
private void log(String message) {
synchronized (Philosopher.class) {
for (var i = 1; i <= this.seat; i++) {
System.out.print(" ");
}
System.out.println(threadId() + " " + message);
}
}
public void stopPhilosopher() {
log("stopping");
this.stop = true;
interrupt();
}
public Philosopher(int seat, Chopstick left, Chopstick right) {
this.stop = false;
this.seat = seat;
this.left = left;
this.right = right;
this.random = new Random();
this.eaten = 0;
}
@Override
public void run() {
log("starting");
try {
while (!this.stop) {
think();
eat();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
log("stopped; eaten=" + this.eaten);
}
private void think() throws InterruptedException {
Thread.sleep(this.random.nextInt(MAX_THINKING_DURATION_MS));
}
private void eat() throws InterruptedException {
log("try taking left");
synchronized (this.left) {
log("left acquired");
Thread.sleep(this.random.nextInt(MAX_TAKING_TIME_MS));
log("try taking right");
synchronized (this.right) {
log("right acquired");
log("eating");
this.eaten++;
Thread.sleep(this.random.nextInt(MAX_EATING_DURATION_MS));
}
log("right released");
}
log("left released");
}
}

View File

@ -0,0 +1,32 @@
package pp;
public class PhilosopherExperiment {
static final int PHILOSOPHER_NUM = 5;
static final int EXP_DURATION_MS = 20000;
public static void main(String... args) throws InterruptedException {
var chopsticks = new Chopstick[PHILOSOPHER_NUM];
var philosophers = new Philosopher[PHILOSOPHER_NUM];
for (int i = 0; i < PHILOSOPHER_NUM; i++) {
chopsticks[i] = new Chopstick();
}
// first n-1 philosophers
for (var i = 0; i < (PHILOSOPHER_NUM - 1); i++) {
philosophers[i] = new Philosopher(i, chopsticks[i], chopsticks[(i + 1)]);
}
// nth philosophers: initialize with right+left instead of left+right
philosophers[PHILOSOPHER_NUM - 1] = new Philosopher(
PHILOSOPHER_NUM - 1,
chopsticks[0],
chopsticks[PHILOSOPHER_NUM - 1]
);
for (var i = 0; i < PHILOSOPHER_NUM; i++) {
philosophers[i].start();
}
Thread.sleep(EXP_DURATION_MS);
for (var i = 0; i < PHILOSOPHER_NUM; i++) {
philosophers[i].stopPhilosopher();
}
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "``wait``/``notifyAll`` für Ringpuffer"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-02-BoundedQueueWaitNotify.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-Solutions.html#laboraufgabe-waitnotifyall-für-ringpuffer)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/03-steuerung.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/03-steuerung.html)

View File

@ -0,0 +1,12 @@
default:
mvn clean compile exec:java
exec args:
mvn exec:java -Dexec.args={{args}}
clean:
mvn clean
compile:
mvn compile
test:
mvn test
javadoc:
mvn javadoc:javadoc

View File

@ -0,0 +1,61 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pp</groupId>
<artifactId>pp.03.02-BoundedQueueWaitNotify</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.BoundedBuffer</exec.mainClass>
<maven.compiler.release>10</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency><!-- für Unit-Tests -->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency><!-- für Lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<dependency><!-- für net.jcip Annotationen -->
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin><!-- für Unit-Tests [mvn test] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin><!-- [mvn compile] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
</plugin>
<plugin><!-- [mvn exec:java] -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin><!-- [mvn javadoc:javadoc] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<show>private</show>
<locale>en_US</locale>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,82 @@
package pp;
public class BoundedBuffer<T> {
final Object[] items = new Object[8];
int putptr, takeptr, count;
public void put(T x) throws InterruptedException {
// solange der Speicher voll ist, warten
this.items[this.putptr] = x;
if (++this.putptr == this.items.length) {
this.putptr = 0;
}
++this.count;
// nun ist etwas neues im Speicher: Alle wartenden Threads
// benachrichtigen
}
public T take() throws InterruptedException {
// solange der Speicher leer ist, warten
@SuppressWarnings("unchecked")
var x = (T) this.items[this.takeptr];
if (++this.takeptr == this.items.length) {
this.takeptr = 0;
}
--this.count;
// nun ist etwas Platz im Speicher: Alle wartenden Threads
// benachrichtigen
return x;
}
public static void main(String... args) throws InterruptedException {
var mem = new BoundedBuffer<Integer>();
var p1 = new Thread(
() -> {
try {
for (var j = 1; j <= 10; j++) {
mem.put(j);
System.out.println(Thread.currentThread().getName() + ": put=" + j);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
},
"Producer-1"
);
var p2 = new Thread(
() -> {
try {
for (var j = 1; j <= 10; j++) {
mem.put(j);
System.out.println(Thread.currentThread().getName() + ": put=" + j);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
},
"Producer-2"
);
var c1 = new Thread(
() -> {
try {
for (var j = 1; j <= 20; j++) {
System.out.println(Thread.currentThread().getName() + ": taken=" + mem.take());
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
},
"Consumer-1"
);
var now = System.currentTimeMillis();
p1.start();
p2.start();
c1.start();
p1.join();
p2.join();
c1.join();
System.out.println("Runtime: " + (System.currentTimeMillis() - now) + "ms");
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "``wait``/``notifyAll`` für Ringpuffer"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-02-BoundedQueueWaitNotify.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-Solutions.html#laboraufgabe-waitnotifyall-für-ringpuffer)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/03-steuerung.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/03-steuerung.html)

View File

@ -0,0 +1,12 @@
default:
mvn clean compile exec:java
exec args:
mvn exec:java -Dexec.args={{args}}
clean:
mvn clean
compile:
mvn compile
test:
mvn test
javadoc:
mvn javadoc:javadoc

View File

@ -0,0 +1,61 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pp</groupId>
<artifactId>pp.03.02-BoundedQueueWaitNotify_solution</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.BoundedBuffer</exec.mainClass>
<maven.compiler.release>10</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency><!-- für Unit-Tests -->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency><!-- für Lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<dependency><!-- für net.jcip Annotationen -->
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin><!-- für Unit-Tests [mvn test] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin><!-- [mvn compile] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
</plugin>
<plugin><!-- [mvn exec:java] -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin><!-- [mvn javadoc:javadoc] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<show>private</show>
<locale>en_US</locale>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,84 @@
package pp;
public class BoundedBuffer<T> {
final Object[] items = new Object[8];
int putptr, takeptr, count;
public synchronized void put(T x) throws InterruptedException {
while (this.count == this.items.length) {
wait();
}
this.items[this.putptr] = x;
if (++this.putptr == this.items.length) {
this.putptr = 0;
}
++this.count;
notifyAll();
}
public synchronized T take() throws InterruptedException {
while (this.count == 0) {
wait();
}
@SuppressWarnings("unchecked")
var x = (T) this.items[this.takeptr];
if (++this.takeptr == this.items.length) {
this.takeptr = 0;
}
--this.count;
notifyAll();
return x;
}
public static void main(String... args) throws InterruptedException {
var mem = new BoundedBuffer<Integer>();
var p1 = new Thread(
() -> {
try {
for (var j = 1; j <= 10; j++) {
mem.put(j);
System.out.println(Thread.currentThread().getName() + ": put=" + j);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
},
"Producer-1"
);
var p2 = new Thread(
() -> {
try {
for (var j = 1; j <= 10; j++) {
mem.put(j);
System.out.println(Thread.currentThread().getName() + ": put=" + j);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
},
"Producer-2"
);
var c1 = new Thread(
() -> {
try {
for (var j = 1; j <= 20; j++) {
System.out.println(Thread.currentThread().getName() + ": taken=" + mem.take());
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
},
"Consumer-1"
);
var now = System.currentTimeMillis();
p1.start();
p2.start();
c1.start();
p1.join();
p2.join();
c1.join();
System.out.println("Runtime: " + (System.currentTimeMillis() - now) + "ms");
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "``await``/``signal`` für Ringpuffer”
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-03-BoundedQueueAwaitSignal.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-Solutions.html#laboraufgabe-awaitsignal-für-ringpuffer)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/03-steuerung.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/03-steuerung.html)

View File

@ -0,0 +1,12 @@
default:
mvn clean compile exec:java
exec args:
mvn exec:java -Dexec.args={{args}}
clean:
mvn clean
compile:
mvn compile
test:
mvn test
javadoc:
mvn javadoc:javadoc

View File

@ -0,0 +1,61 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pp</groupId>
<artifactId>pp.03.03-BoundedQueueAwaitSignal</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.BoundedBuffer</exec.mainClass>
<maven.compiler.release>10</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency><!-- für Unit-Tests -->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency><!-- für Lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<dependency><!-- für net.jcip Annotationen -->
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin><!-- für Unit-Tests [mvn test] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin><!-- [mvn compile] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
</plugin>
<plugin><!-- [mvn exec:java] -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin><!-- [mvn javadoc:javadoc] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<show>private</show>
<locale>en_US</locale>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,92 @@
package pp;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class BoundedBuffer<T> {
final Lock lock = new ReentrantLock();
final Condition notFull = this.lock.newCondition();
final Condition notEmpty = this.lock.newCondition();
final Object[] items = new Object[8];
int putptr, takeptr, count;
public void put(T x) throws InterruptedException {
// solange der Speicher voll ist, warten
this.items[this.putptr] = x;
if (++this.putptr == this.items.length) {
this.putptr = 0;
}
++this.count;
// nun ist etwas neues im Speicher: Alle wartenden Threads
// benachrichtigen
}
public T take() throws InterruptedException {
// solange der Speicher leer ist, mit der Bedingungsvariablen notEmpty
// warten
@SuppressWarnings("unchecked")
var x = (T) this.items[this.takeptr];
if (++this.takeptr == this.items.length) {
this.takeptr = 0;
}
--this.count;
// nun ist etwas Platz im Speicher: Alle für notFull wartenden Threads
// benachrichtigen
return x;
}
public static void main(String... args) throws InterruptedException {
var mem = new BoundedBuffer<Integer>();
var p1 = new Thread(
() -> {
try {
for (var j = 1; j <= 10; j++) {
mem.put(j);
System.out.println(Thread.currentThread().getName() + ": put=" + j);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
},
"Producer-1"
);
var p2 = new Thread(
() -> {
try {
for (var j = 1; j <= 10; j++) {
mem.put(j);
System.out.println(Thread.currentThread().getName() + ": put=" + j);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
},
"Producer-2"
);
var c1 = new Thread(
() -> {
try {
for (var j = 1; j <= 20; j++) {
System.out.println(Thread.currentThread().getName() + ": taken=" + mem.take());
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
},
"Consumer-1"
);
var now = System.currentTimeMillis();
p1.start();
p2.start();
c1.start();
p1.join();
p2.join();
c1.join();
System.out.println("Runtime: " + (System.currentTimeMillis() - now) + "ms");
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "``await``/``signal`` für Ringpuffer”
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-03-BoundedQueueAwaitSignal.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/03-Solutions.html#laboraufgabe-awaitsignal-für-ringpuffer)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/03-steuerung.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/03-steuerung.html)

View File

@ -0,0 +1,12 @@
default:
mvn clean compile exec:java
exec args:
mvn exec:java -Dexec.args={{args}}
clean:
mvn clean
compile:
mvn compile
test:
mvn test
javadoc:
mvn javadoc:javadoc

View File

@ -0,0 +1,61 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pp</groupId>
<artifactId>pp.03.03-BoundedQueueAwaitSignal_solution</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.BoundedBuffer</exec.mainClass>
<maven.compiler.release>10</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency><!-- für Unit-Tests -->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency><!-- für Lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<dependency><!-- für net.jcip Annotationen -->
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin><!-- für Unit-Tests [mvn test] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin><!-- [mvn compile] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
</plugin>
<plugin><!-- [mvn exec:java] -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin><!-- [mvn javadoc:javadoc] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<show>private</show>
<locale>en_US</locale>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,96 @@
package pp;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class BoundedBuffer<T> {
final Lock lock = new ReentrantLock();
final Condition notFull = this.lock.newCondition();
final Condition notEmpty = this.lock.newCondition();
final Object[] items = new Object[8];
int putptr, takeptr, count;
public void put(T x) throws InterruptedException {
this.lock.lock();
try {
while (this.count == this.items.length) {
this.notFull.await(); // unlock falls Bedingung
}
this.items[this.putptr] = x;
if (++this.putptr == this.items.length) {
this.putptr = 0;
}
++this.count;
this.notEmpty.signal();
} finally {
this.lock.unlock();
}
}
public T take() throws InterruptedException {
this.lock.lock();
try {
while (this.count == 0) {
this.notEmpty.await();
}
@SuppressWarnings("unchecked")
var x = (T) this.items[this.takeptr];
if (++this.takeptr == this.items.length) {
this.takeptr = 0;
}
--this.count;
this.notFull.signal();
return x;
} finally {
this.lock.unlock();
}
}
public static void main(String... args) throws InterruptedException {
var mem = new BoundedBuffer<Integer>();
var p1 = new Thread(() -> {
try {
for (var j = 1; j <= 10; j++) {
mem.put(j);
System.out.println(
Thread.currentThread().getName() + ": put=" + j);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Producer-1");
var p2 = new Thread(() -> {
try {
for (var j = 1; j <= 10; j++) {
mem.put(j);
System.out.println(
Thread.currentThread().getName() + ": put=" + j);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Producer-2");
var c1 = new Thread(() -> {
try {
for (var j = 1; j <= 20; j++) {
System.out.println(Thread.currentThread().getName()
+ ": taken=" + mem.take());
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Consumer-1");
var now = System.currentTimeMillis();
p1.start();
p2.start();
c1.start();
p1.join();
p2.join();
c1.join();
System.out.println(
"Runtime: " + (System.currentTimeMillis() - now) + "ms");
}
}