forked from Parallele_Programmierung/Labs
initial
parent
08037aa595
commit
fbb4d157a5
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Laboraufgabe "Unterbrechbarkeit von Threads, die blockiert sind"
|
||||||
|
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-01-SynchInterrupt.html)
|
||||||
|
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-Solutions.html#laboraufgabe-unterbrechbarkeit-von-threads-die-blockiert-sind")
|
||||||
|
|
||||||
|
# Materialien
|
||||||
|
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/06-locks.html)
|
||||||
|
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/06-locks.html)
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
default:
|
||||||
|
just exec pp.Task ""
|
||||||
|
|
||||||
|
exec class args: compile
|
||||||
|
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
|
||||||
|
clean:
|
||||||
|
mvn clean
|
||||||
|
compile:
|
||||||
|
mvn compile
|
||||||
|
test: compile
|
||||||
|
mvn test
|
||||||
|
javadoc:
|
||||||
|
mvn javadoc:javadoc
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<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.06.01.SynchInterrupt</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<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>
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
public class Task extends Thread {
|
||||||
|
private volatile boolean stop = false;
|
||||||
|
|
||||||
|
public Task(String name) {
|
||||||
|
setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void kill() {
|
||||||
|
System.out.printf("%s: killing...\n", getName());
|
||||||
|
this.stop = true;
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
System.out.printf("%s: startup\n", getName());
|
||||||
|
while (!this.stop) {
|
||||||
|
try {
|
||||||
|
synchronized (Task.class) {
|
||||||
|
System.out.printf("%s: working\n", getName());
|
||||||
|
Thread.sleep(8000);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.printf("%s: interrupted\n", getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.printf("%s: finished\n", getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
var t1 = new Task("T1");
|
||||||
|
var t2 = new Task("T2");
|
||||||
|
var t3 = new Task("T3");
|
||||||
|
t1.start();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
t2.start();
|
||||||
|
t3.start();
|
||||||
|
t2.kill();
|
||||||
|
t3.kill();
|
||||||
|
t1.kill();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Laboraufgabe "Unterbrechbarkeit von Threads, die blockiert sind"
|
||||||
|
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-01-SynchInterrupt.html)
|
||||||
|
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-Solutions.html#laboraufgabe-unterbrechbarkeit-von-threads-die-blockiert-sind")
|
||||||
|
|
||||||
|
# Materialien
|
||||||
|
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/06-locks.html)
|
||||||
|
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/06-locks.html)
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
default:
|
||||||
|
just exec pp.Task ""
|
||||||
|
|
||||||
|
exec class args: compile
|
||||||
|
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
|
||||||
|
clean:
|
||||||
|
mvn clean
|
||||||
|
compile:
|
||||||
|
mvn compile
|
||||||
|
test: compile
|
||||||
|
mvn test
|
||||||
|
javadoc:
|
||||||
|
mvn javadoc:javadoc
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<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.06.01.SynchInterrupt_solution</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<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>
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
public class Task extends Thread {
|
||||||
|
private volatile boolean stop = false;
|
||||||
|
|
||||||
|
public Task(String name) {
|
||||||
|
setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void kill() {
|
||||||
|
System.out.printf("%s: killing...\n", getName());
|
||||||
|
this.stop = true;
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
System.out.printf("%s: startup\n", getName());
|
||||||
|
while (!this.stop) {
|
||||||
|
try {
|
||||||
|
synchronized (Task.class) {
|
||||||
|
System.out.printf("%s: working\n", getName());
|
||||||
|
Thread.sleep(8000);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.printf("%s: interrupted\n", getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.printf("%s: finished\n", getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
var t1 = new Task("T1");
|
||||||
|
var t2 = new Task("T2");
|
||||||
|
var t3 = new Task("T3");
|
||||||
|
t1.start();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
t2.start();
|
||||||
|
t3.start();
|
||||||
|
t2.kill();
|
||||||
|
t3.kill();
|
||||||
|
t1.kill();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class TaskInterruptably extends Thread {
|
||||||
|
private volatile boolean stop = false;
|
||||||
|
private static Lock lock = new ReentrantLock();
|
||||||
|
|
||||||
|
public TaskInterruptably(String name) {
|
||||||
|
setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void kill() {
|
||||||
|
System.out.printf("%s: killing...\n", getName());
|
||||||
|
this.stop = true;
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
System.out.printf("%s: startup\n", getName());
|
||||||
|
while (!this.stop) {
|
||||||
|
try {
|
||||||
|
lock.lockInterruptibly();
|
||||||
|
try {
|
||||||
|
System.out.printf("%s: working\n", getName());
|
||||||
|
Thread.sleep(8000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.printf("%s: interrupted (inner)\n", getName());
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.printf("%s: interrupted (outer)\n", getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.printf("%s: finished\n", getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
var t1 = new TaskInterruptably("T1");
|
||||||
|
var t2 = new TaskInterruptably("T2");
|
||||||
|
var t3 = new TaskInterruptably("T3");
|
||||||
|
t1.start();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
t2.start();
|
||||||
|
t3.start();
|
||||||
|
t2.kill();
|
||||||
|
t3.kill();
|
||||||
|
t1.kill();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class TaskRegular extends Thread {
|
||||||
|
private volatile boolean stop = false;
|
||||||
|
private static Lock lock = new ReentrantLock();
|
||||||
|
|
||||||
|
public TaskRegular(String name) {
|
||||||
|
setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void kill() {
|
||||||
|
System.out.printf("%s: killing...\n", getName());
|
||||||
|
this.stop = true;
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
System.out.printf("%s: startup\n", getName());
|
||||||
|
while (!this.stop) {
|
||||||
|
var blocked = true;
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
blocked = false;
|
||||||
|
System.out.printf("%s: working\n", getName());
|
||||||
|
Thread.sleep(8000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
if (blocked) {
|
||||||
|
System.out.printf("%s: blocked state interrupted\n",
|
||||||
|
getName());
|
||||||
|
} else {
|
||||||
|
System.out.printf("%s: interrupted\n", getName());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.printf("%s: finished\n", getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
var t1 = new TaskRegular("T1");
|
||||||
|
var t2 = new TaskRegular("T2");
|
||||||
|
var t3 = new TaskRegular("T3");
|
||||||
|
t1.start();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
t2.start();
|
||||||
|
t3.start();
|
||||||
|
t2.kill();
|
||||||
|
t3.kill();
|
||||||
|
t1.kill();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Laboraufgabe “Vergleich von ``ReentrantLock``, ``ReentrantReadWriteLock``, ``StampedLock`` und ``synchronized``”
|
||||||
|
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-02-LockTiming.html)
|
||||||
|
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-Solutions.html#laboraufgabe-vergleich-von-reentrantlock-reentrantreadwritelock-stampedlock-und-synchronized")
|
||||||
|
|
||||||
|
# Materialien
|
||||||
|
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/06-locks.html)
|
||||||
|
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/06-locks.html)
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
default:
|
||||||
|
just exec pp.ExpUnsynchronized ""
|
||||||
|
|
||||||
|
exec class args: compile
|
||||||
|
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
|
||||||
|
clean:
|
||||||
|
mvn clean
|
||||||
|
compile:
|
||||||
|
mvn compile
|
||||||
|
test: compile
|
||||||
|
mvn test
|
||||||
|
javadoc:
|
||||||
|
mvn javadoc:javadoc
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
<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.06.02-LockTiming</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.release>10</maven.compiler.release>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository><!-- für Lombok (neueste Version >= 1.20 für @Locked)-->
|
||||||
|
<id>projectlombok.org</id>
|
||||||
|
<url>https://projectlombok.org/edge-releases</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<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 (neueste Version >= 1.20 für @Locked)-->
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>edge-SNAPSHOT</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>
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
public class ExpUnsynchronized extends Experiment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void incCounter() {
|
||||||
|
this.counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCounter() {
|
||||||
|
return this.counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
(new ExpUnsynchronized()).experimentPar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
public abstract class Experiment {
|
||||||
|
static final int WRITES = 1; // 5000
|
||||||
|
static final int READS = 9999; // 5000
|
||||||
|
static final int TRIALS = 100000000 / (WRITES + READS);
|
||||||
|
|
||||||
|
protected int counter;
|
||||||
|
|
||||||
|
public void experimentSingle() {
|
||||||
|
for (var i = 0; i < TRIALS; i++) {
|
||||||
|
for (var j = 0; j < WRITES; j++) {
|
||||||
|
incCounter();
|
||||||
|
}
|
||||||
|
for (var j = 0; j < READS; j++) {
|
||||||
|
getCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void experimentPar() throws InterruptedException {
|
||||||
|
var t1 = new Thread(() -> experimentSingle());
|
||||||
|
var t2 = new Thread(() -> experimentSingle());
|
||||||
|
var now = System.currentTimeMillis();
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
System.out
|
||||||
|
.printf("Lauf %s, Zeitdauer: %dms",
|
||||||
|
(getCounter() - (2 * TRIALS * WRITES)) == 0 ? "korrekt"
|
||||||
|
: "fehlerhaft",
|
||||||
|
System.currentTimeMillis() - now);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void incCounter();
|
||||||
|
|
||||||
|
public abstract int getCounter();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Laboraufgabe “Vergleich von ``ReentrantLock``, ``ReentrantReadWriteLock``, ``StampedLock`` und ``synchronized``”
|
||||||
|
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-02-LockTiming.html)
|
||||||
|
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-Solutions.html#laboraufgabe-vergleich-von-reentrantlock-reentrantreadwritelock-stampedlock-und-synchronized")
|
||||||
|
|
||||||
|
# Materialien
|
||||||
|
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/06-locks.html)
|
||||||
|
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/06-locks.html)
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
default:
|
||||||
|
just exec pp.Main ""
|
||||||
|
|
||||||
|
run experiment:
|
||||||
|
just exec pp.{{experiment}} ""
|
||||||
|
|
||||||
|
exec class args: compile
|
||||||
|
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
|
||||||
|
clean:
|
||||||
|
mvn clean
|
||||||
|
compile:
|
||||||
|
mvn compile
|
||||||
|
test: compile
|
||||||
|
mvn test
|
||||||
|
javadoc:
|
||||||
|
mvn javadoc:javadoc
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
<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.06.02-LockTiming_solution</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.release>10</maven.compiler.release>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository><!-- für Lombok (neueste Version >= 1.20 für @Locked)-->
|
||||||
|
<id>projectlombok.org</id>
|
||||||
|
<url>https://projectlombok.org/edge-releases</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<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 (neueste Version >= 1.20 für @Locked)-->
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>edge-SNAPSHOT</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>
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;;
|
||||||
|
|
||||||
|
public class ExpReadWriteLock extends Experiment {
|
||||||
|
private final ReadWriteLock lock;
|
||||||
|
private final Lock rLock;
|
||||||
|
private final Lock wLock;
|
||||||
|
|
||||||
|
public ExpReadWriteLock() {
|
||||||
|
this.lock = new ReentrantReadWriteLock(false); // fair==true => (noch)
|
||||||
|
// langsamer
|
||||||
|
this.rLock = this.lock.readLock();
|
||||||
|
this.wLock = this.lock.writeLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void incCounter() {
|
||||||
|
this.wLock.lock();
|
||||||
|
try {
|
||||||
|
this.counter++;
|
||||||
|
} finally {
|
||||||
|
this.wLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCounter() {
|
||||||
|
this.rLock.lock();
|
||||||
|
try {
|
||||||
|
return this.counter;
|
||||||
|
} finally {
|
||||||
|
this.rLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
(new ExpReadWriteLock()).experimentPar();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import lombok.Locked;
|
||||||
|
|
||||||
|
public class ExpReadWriteLockLombok extends Experiment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Locked.Write
|
||||||
|
public void incCounter() {
|
||||||
|
this.counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Locked.Read
|
||||||
|
public int getCounter() {
|
||||||
|
return this.counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
(new ExpReadWriteLock()).experimentPar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class ExpReentrantLock extends Experiment {
|
||||||
|
private final ReentrantLock lock;
|
||||||
|
|
||||||
|
public ExpReentrantLock() {
|
||||||
|
this.lock = new ReentrantLock(false); // fair==true => (noch) langsamer
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void incCounter() {
|
||||||
|
this.lock.lock();
|
||||||
|
try {
|
||||||
|
this.counter++;
|
||||||
|
} finally {
|
||||||
|
this.lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCounter() {
|
||||||
|
this.lock.lock();
|
||||||
|
try {
|
||||||
|
return this.counter;
|
||||||
|
} finally {
|
||||||
|
this.lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
(new ExpReentrantLock()).experimentPar();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import lombok.Locked;
|
||||||
|
|
||||||
|
public class ExpReentrantLockLombok extends Experiment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Locked
|
||||||
|
public void incCounter() {
|
||||||
|
this.counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Locked
|
||||||
|
public int getCounter() {
|
||||||
|
return this.counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
(new ExpReentrantLock()).experimentPar();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.StampedLock;;
|
||||||
|
|
||||||
|
public class ExpStampedLock extends Experiment {
|
||||||
|
private final StampedLock lock;
|
||||||
|
|
||||||
|
public ExpStampedLock() {
|
||||||
|
this.lock = new StampedLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void incCounter() {
|
||||||
|
var stamp = this.lock.writeLock();
|
||||||
|
try {
|
||||||
|
this.counter++;
|
||||||
|
} finally {
|
||||||
|
this.lock.unlockWrite(stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCounter() {
|
||||||
|
var stamp = this.lock.tryOptimisticRead();
|
||||||
|
var result = this.counter;
|
||||||
|
if (!this.lock.validate(stamp)) {
|
||||||
|
// nicht erfolgreich
|
||||||
|
stamp = this.lock.readLock();
|
||||||
|
try {
|
||||||
|
result = this.counter;
|
||||||
|
} finally {
|
||||||
|
this.lock.unlockRead(stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
(new ExpStampedLock()).experimentPar();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
public class ExpSynchronized extends Experiment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void incCounter() {
|
||||||
|
this.counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized int getCounter() {
|
||||||
|
return this.counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
(new ExpSynchronized()).experimentPar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import lombok.Synchronized;
|
||||||
|
|
||||||
|
public class ExpSynchronizedLombok extends Experiment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Synchronized
|
||||||
|
public void incCounter() {
|
||||||
|
this.counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Synchronized
|
||||||
|
public int getCounter() {
|
||||||
|
return this.counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
(new ExpSynchronized()).experimentPar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
public class ExpUnsynchronized extends Experiment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void incCounter() {
|
||||||
|
this.counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCounter() {
|
||||||
|
return this.counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
(new ExpUnsynchronized()).experimentPar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
public abstract class Experiment {
|
||||||
|
static final int WRITES = 1; // 5000
|
||||||
|
static final int READS = 9999; // 5000
|
||||||
|
static final int TRIALS = 100000000 / (WRITES + READS);
|
||||||
|
|
||||||
|
protected int counter;
|
||||||
|
|
||||||
|
public void experimentSingle() {
|
||||||
|
for (var i = 0; i < TRIALS; i++) {
|
||||||
|
for (var j = 0; j < WRITES; j++) {
|
||||||
|
incCounter();
|
||||||
|
}
|
||||||
|
for (var j = 0; j < READS; j++) {
|
||||||
|
getCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void experimentPar() throws InterruptedException {
|
||||||
|
var t1 = new Thread(() -> experimentSingle());
|
||||||
|
var t2 = new Thread(() -> experimentSingle());
|
||||||
|
var now = System.currentTimeMillis();
|
||||||
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
System.out
|
||||||
|
.printf("Lauf %s, Zeitdauer: %dms",
|
||||||
|
(getCounter() - (2 * TRIALS * WRITES)) == 0 ? "korrekt"
|
||||||
|
: "fehlerhaft",
|
||||||
|
System.currentTimeMillis() - now);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void incCounter();
|
||||||
|
|
||||||
|
public abstract int getCounter();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static void main(String... args) throws InterruptedException {
|
||||||
|
System.out.print("StampedLock: ");
|
||||||
|
ExpStampedLock.main(args);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.print("ReentrantLock: ");
|
||||||
|
ExpReentrantLock.main(args);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.print("ReentrantLock (Lombok): ");
|
||||||
|
ExpReentrantLockLombok.main(args);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.print("Synchronized: ");
|
||||||
|
ExpSynchronized.main(args);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.print("Synchronized (Lombok): ");
|
||||||
|
ExpSynchronizedLombok.main(args);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.print("ReentrantReadWriteLock: ");
|
||||||
|
ExpReadWriteLock.main(args);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.print("ReentrantReadWriteLock (Lombok): ");
|
||||||
|
ExpReadWriteLockLombok.main(args);
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue