pull/1/head
Sandro Leuchter 2024-10-06 20:54:45 +02:00
parent da8f59294f
commit 1573cc159d
38 changed files with 1195 additions and 0 deletions

View File

@ -0,0 +1,7 @@
# Laboraufgabe "Anwendung von Memory Barrieren"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-01-MemoryBarrier.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-Solutions.html#laboraufgabe-anwendung-von-memory-barrieren)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/02-konkurrierenderZugriff.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/02-konkurrierenderZugriff.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.02.01-MemoryBarrier</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.MemoryBarrierTest</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,24 @@
package pp;
public class MemoryBarrierTest extends Thread {
public boolean stopped = false;
@Override
public void run() {
while (!this.stopped) {
// work
}
System.out.println("MemoryBarrierTest-Thread actually stopped.");
}
public static void main(String... args) throws InterruptedException {
var t = new MemoryBarrierTest();
t.start();
Thread.sleep(1000);
t.stopped = true;
System.out.println(
"Main thread set stopped on MemoryBarrierTest-Thread.");
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "Anwendung von Memory Barrieren"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-01-MemoryBarrier.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-Solutions.html#laboraufgabe-anwendung-von-memory-barrieren)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/02-konkurrierenderZugriff.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/02-konkurrierenderZugriff.html)

View File

@ -0,0 +1,25 @@
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
_exec class: clean compile
mvn exec:java -Dexec.mainClass="pp.{{class}}" -Dexec.args=""
MemoryBarrierTest1:
just _exec MemoryBarrierTest1
MemoryBarrierTest1b:
just _exec MemoryBarrierTest1b
MemoryBarrierTest2:
just _exec MemoryBarrierTest2
MemoryBarrierTest5:
just _exec MemoryBarrierTest5
MemoryBarrierTest6:
just _exec MemoryBarrierTest6

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.02.01-MemoryBarrier_solution</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.MemoryBarrierTest1</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,26 @@
package pp;
public class MemoryBarrierTest1 extends Thread {
// Markierung von stopped als volatile => Jede Änderung wirkt als
// Memory-Barrier
public volatile boolean stopped = false;
@Override
public void run() {
while (!this.stopped) {
// work
}
System.out.println("MemoryBarrierTest-Thread actually stopped.");
}
public static void main(String... args) throws InterruptedException {
var t = new MemoryBarrierTest1();
t.start();
Thread.sleep(1000);
t.stopped = true;
System.out.println(
"Main thread set stopped on MemoryBarrierTest-Thread.");
}
}

View File

@ -0,0 +1,36 @@
package pp;
public class MemoryBarrierTest1b extends Thread {
private boolean stopped = false;
// lesende Zugriffe auf this.stopped über synchronized Getter => wirkt als
// Memory-Barrier (Pull)
public synchronized boolean getStopped() {
return this.stopped;
}
// ändernde Zugriffe auf this.stopped über synchronized Setter => wirkt als
// Memory-Barrier (Push)
public synchronized void setStopped(boolean stopped) {
this.stopped = stopped;
}
@Override
public void run() {
while (!getStopped()) {
// work
}
System.out.println("MemoryBarrierTest-Thread actually stopped.");
}
public static void main(String... args) throws InterruptedException {
var t = new MemoryBarrierTest1b();
t.start();
Thread.sleep(1000);
t.setStopped(true);
System.out.println(
"Main thread set stopped on MemoryBarrierTest-Thread.");
}
}

View File

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

View File

@ -0,0 +1,46 @@
package pp;
public class MemoryBarrierTest5 extends Thread {
public boolean stopped = false;
private Thread stopper;
public void startStopper() {
this.stopper = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
this.stopped = true;
System.out.println(
"Stopper thread set stopped on MemoryBarrierTest-Thread.");
});
this.stopper.start();
}
@Override
public void run() {
startStopper();
while (!this.stopped) {
// work
if (this.stopper != null) {
try {
// Synchronisierung von Stopper-Thread Variablenänderungen
// durch Warten auf das Ende von Stopper Thread
this.stopper.join(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
System.out.println("MemoryBarrierTest-Thread actually stopped.");
}
public static void main(String... args) throws InterruptedException {
var t = new MemoryBarrierTest5();
t.start();
}
}

View File

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

View File

@ -0,0 +1,7 @@
# Laboraufgabe "threadlokaler Speicher"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-02-ThreadLocal.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-Solutions.html#laboraufgabe-threadlokaler-speicher)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/02-konkurrierenderZugriff.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/02-konkurrierenderZugriff.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.02.02-ThreadLocal</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.MyThreadLocalRandom</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,26 @@
package pp;
import java.util.Random;
public class MyThreadLocalRandom implements Runnable {
public static long now = System.currentTimeMillis();
public Random rand = new Random(now);
@Override
public void run() {
var strBuf = new StringBuffer();
strBuf.append(Thread.currentThread().getName() + ": ");
for (var j = 0; j < 20; j++) {
strBuf.append(String.format("%2d ", this.rand.nextInt(100)));
}
System.out.println(strBuf);
}
public static void main(String... args) {
var runner = new MyThreadLocalRandom();
for (var i = 0; i < 10; i++) {
new Thread(runner, String.format("Runner-%02d", i)).start();
}
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "threadlokaler Speicher"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-02-ThreadLocal.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-Solutions.html#laboraufgabe-threadlokaler-speicher)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/02-konkurrierenderZugriff.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/02-konkurrierenderZugriff.html)

View File

@ -0,0 +1,25 @@
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
_exec class: clean compile
mvn exec:java -Dexec.mainClass="pp.{{class}}" -Dexec.args=""
MyThreadLocalRandom0:
just _exec MyThreadLocalRandom0
MyThreadLocalRandom1:
just _exec MyThreadLocalRandom1
MyThreadLocalRandom2:
just _exec MyThreadLocalRandom2
MyThreadLocalRandom3:
just _exec MyThreadLocalRandom3
MyThreadLocalRandom4:
just _exec MyThreadLocalRandom4

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.02.02-ThreadLocal_solution</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.MyThreadLocalRandom0</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,25 @@
package pp;
import java.util.Random;
public class MyThreadLocalRandom0 implements Runnable {
public static long now = System.currentTimeMillis();
public Random rand = new Random(now);
@Override
public void run() {
var strBuf = new StringBuffer();
strBuf.append(Thread.currentThread().getName() + ": ");
for (var j = 0; j < 20; j++) {
strBuf.append(String.format("%02d ", this.rand.nextInt(100)));
}
System.out.println(strBuf);
}
public static void main(String... args) {
var runner = new MyThreadLocalRandom0();
for (var i = 0; i < 10; i++) {
new Thread(runner, String.format("Runner-%02d", i)).start();
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,7 @@
# Laboraufgabe "gegenseitiger Ausschluss"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-03-Lock.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-Solutions.html#laboraufgabe-gegenseitiger-ausschluss)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/02-konkurrierenderZugriff.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/02-konkurrierenderZugriff.html)

View File

@ -0,0 +1,17 @@
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
_exec factory: clean compile
mvn exec:java -Dexec.mainClass="pp.{{factory}}" -Dexec.args=""
Factory:
just _exec Factory

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.02.03-Lock</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.Factory</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,39 @@
package pp;
public class Factory {
private static Type instance;
private static Object lock = new Object();
public static Type getInstance() {
Type.prepare();
if (instance == null) {
instance = new Type();
}
return instance;
}
public static void main(String... args) throws InterruptedException {
var now = System.currentTimeMillis();
var threads = new Thread[100];
for (var i = 0; i < 100; i++) {
threads[i] = new Thread(
() -> {
Type object = Factory.getInstance();
System.out.println(
Thread.currentThread().getName() +
": serial of instance = " +
object.getSerial()
);
},
String.format("InstanceGrabber-%02d", i)
);
threads[i].start();
}
for (var i = 0; i < 100; i++) {
threads[i].join();
}
var time = System.currentTimeMillis() - now;
System.out.println("Dauer: " + time + "ms");
}
}

View File

@ -0,0 +1,38 @@
package pp;
import net.jcip.annotations.*;
@ThreadSafe
public final class Type {
private static int counter = 0;
private int serial = 0;
private int number = 0;
public static void prepare() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public Type() {
synchronized (Type.class) {
Type.counter++;
this.serial = Type.counter;
}
}
public synchronized int getNumber() {
return this.number;
}
public synchronized void setNumber(int number) {
this.number = number;
}
public synchronized int getSerial() {
return this.serial;
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "gegenseitiger Ausschluss"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-03-Lock.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/02-Solutions.html#laboraufgabe-gegenseitiger-ausschluss)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/02-konkurrierenderZugriff.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/02-konkurrierenderZugriff.html)

View File

@ -0,0 +1,25 @@
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
_exec class: clean compile
mvn exec:java -Dexec.mainClass="pp.{{class}}" -Dexec.args=""
Factory0:
just _exec Factory0
Factory1:
just _exec Factory1
Factory2:
just _exec Factory2
Factory3:
just _exec Factory3
Factory4:
just _exec Factory4

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.02.03-Lock_solution</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.Factory0</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,38 @@
package pp;
public class Factory0 {
private static Type instance;
public static Type getInstance() {
Type.prepare();
if (instance == null) {
instance = new Type();
}
return instance;
}
public static void main(String... args) throws InterruptedException {
var now = System.currentTimeMillis();
var threads = new Thread[100];
for (var i = 0; i < 100; i++) {
threads[i] = new Thread(
() -> {
var object = getInstance();
System.out.println(
Thread.currentThread().getName() +
": serial of instance = " +
object.getSerial()
);
},
String.format("InstanceGrabber-%02d", i)
);
threads[i].start();
}
for (var i = 0; i < 100; i++) {
threads[i].join();
}
var time = System.currentTimeMillis() - now;
System.out.println("Dauer: " + time + "ms");
}
}

View File

@ -0,0 +1,38 @@
package pp;
public class Factory1 {
private static Type instance;
public static synchronized Type getInstance() {
Type.prepare();
if (instance == null) {
instance = new Type();
}
return instance;
}
public static void main(String... args) throws InterruptedException {
var now = System.currentTimeMillis();
var threads = new Thread[100];
for (var i = 0; i < 100; i++) {
threads[i] = new Thread(
() -> {
var object = getInstance();
System.out.println(
Thread.currentThread().getName() +
": serial of instance = " +
object.getSerial()
);
},
String.format("InstanceGrabber-%02d", i)
);
threads[i].start();
}
for (var i = 0; i < 100; i++) {
threads[i].join();
}
var time = System.currentTimeMillis() - now;
System.out.println("Dauer: " + time + "ms");
}
}

View File

@ -0,0 +1,40 @@
package pp;
public class Factory2 {
private static volatile Type instance;
public static Type getInstance() {
Type.prepare();
synchronized (Factory2.class) {
if (instance == null) {
instance = new Type();
}
}
return instance;
}
public static void main(String... args) throws InterruptedException {
var now = System.currentTimeMillis();
var threads = new Thread[100];
for (var i = 0; i < 100; i++) {
threads[i] = new Thread(
() -> {
var object = getInstance();
System.out.println(
Thread.currentThread().getName() +
": serial of instance = " +
object.getSerial()
);
},
String.format("InstanceGrabber-%02d", i)
);
threads[i].start();
}
for (var i = 0; i < 100; i++) {
threads[i].join();
}
var time = System.currentTimeMillis() - now;
System.out.println("Dauer: " + time + "ms");
}
}

View File

@ -0,0 +1,41 @@
package pp;
public class Factory3 {
private static volatile Type instance;
private static Object lock = new Object();
public static Type getInstance() {
Type.prepare();
synchronized (lock) {
if (instance == null) {
instance = new Type();
}
}
return instance;
}
public static void main(String... args) throws InterruptedException {
var now = System.currentTimeMillis();
var threads = new Thread[100];
for (var i = 0; i < 100; i++) {
threads[i] = new Thread(
() -> {
var object = Factory3.getInstance();
System.out.println(
Thread.currentThread().getName() +
": serial of instance = " +
object.getSerial()
);
},
String.format("InstanceGrabber-%02d", i)
);
threads[i].start();
}
for (var i = 0; i < 100; i++) {
threads[i].join();
}
var time = System.currentTimeMillis() - now;
System.out.println("Dauer: " + time + "ms");
}
}

View File

@ -0,0 +1,42 @@
package pp;
public class Factory4 {
private static volatile Type instance;
public static Type getInstance() {
Type.prepare();
if (instance == null) {
synchronized (Factory4.class) {
if (instance == null) {
instance = new Type();
}
}
}
return instance;
}
public static void main(String... args) throws InterruptedException {
var now = System.currentTimeMillis();
var threads = new Thread[100];
for (var i = 0; i < 100; i++) {
threads[i] = new Thread(
() -> {
var object = getInstance();
System.out.println(
Thread.currentThread().getName() +
": serial of instance = " +
object.getSerial()
);
},
String.format("InstanceGrabber-%02d", i)
);
threads[i].start();
}
for (var i = 0; i < 100; i++) {
threads[i].join();
}
var time = System.currentTimeMillis() - now;
System.out.println("Dauer: " + time + "ms");
}
}

View File

@ -0,0 +1,38 @@
package pp;
import net.jcip.annotations.*;
@ThreadSafe
public final class Type {
private static int counter = 0;
private int serial = 0;
private int number = 0;
public static void prepare() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public Type() {
synchronized (Type.class) {
Type.counter++;
this.serial = Type.counter;
}
}
public synchronized int getNumber() {
return this.number;
}
public synchronized void setNumber(int number) {
this.number = number;
}
public synchronized int getSerial() {
return this.serial;
}
}