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