forked from Parallele_Programmierung/Labs
initial Kap. 10
parent
53803a654a
commit
7334686720
|
|
@ -0,0 +1,9 @@
|
|||
# Laboraufgabe "naive ``Exchanger``-Implementierung"
|
||||
|
||||
Dies hier ist eine naive (und teilweise) Implementierung eines [Exchangers](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Exchanger.html).
|
||||
|
||||
Die reale Implementierung ist weitaus komplexer: https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/concurrent/Exchanger.java
|
||||
|
||||
# Materialien
|
||||
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/10-csp.html)
|
||||
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/i10-csp.html)
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<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.10.00-Exchanger</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<properties>
|
||||
<maven.compiler.release>10</maven.compiler.release>
|
||||
<lombok.version>edge-SNAPSHOT</lombok.version>
|
||||
<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>${lombok.version}</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>
|
||||
<defaultGoal>clean compile test</defaultGoal>
|
||||
<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>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</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,30 @@
|
|||
package pp;
|
||||
|
||||
import net.jcip.annotations.ThreadSafe;
|
||||
|
||||
@ThreadSafe
|
||||
public class SimpleExchanger<T> {
|
||||
private T left, right;
|
||||
private Object monitor = new Object();
|
||||
|
||||
public T exchange(T data) throws InterruptedException {
|
||||
synchronized (this.monitor) {
|
||||
if (this.left == null && this.right == null) {
|
||||
this.left = data;
|
||||
while (this.right == null) {
|
||||
this.monitor.wait();
|
||||
}
|
||||
return this.right;
|
||||
} else {
|
||||
this.right = data;
|
||||
this.monitor.notify();
|
||||
try {
|
||||
return this.left;
|
||||
} finally {
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package pp;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ExchangerTest {
|
||||
final private SimpleExchanger<Integer> e = new SimpleExchanger<>();
|
||||
|
||||
@Test
|
||||
void test1() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
assertEquals(Integer.valueOf(2), e.exchange(Integer.valueOf(1)));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}).start();
|
||||
new Thread(() -> {
|
||||
try {
|
||||
assertEquals(Integer.valueOf(1), e.exchange(Integer.valueOf(2)));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Test
|
||||
void test2() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
assertEquals(Integer.valueOf(3), e.exchange(Integer.valueOf(4)));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}).start();
|
||||
new Thread(() -> {
|
||||
try {
|
||||
assertEquals(Integer.valueOf(4), e.exchange(Integer.valueOf(3)));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Test
|
||||
void test3() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
assertEquals(Integer.valueOf(5), e.exchange(Integer.valueOf(6)));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}).start();
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
assertEquals(Integer.valueOf(6), e.exchange(Integer.valueOf(5)));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Laboraufgabe "CSP mit Java-Mitteln"
|
||||
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/10-01-Rendezvous.html)
|
||||
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/10-Solutions.html#laboraufgabe-csp-mit-java-mitteln)
|
||||
|
||||
# Materialien
|
||||
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/10-csp.html)
|
||||
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/i10-csp.html)
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<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.10.01.Rendezvous</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<exec.mainClass>io.dama.ffi.rendezvous.Sum</exec.mainClass>
|
||||
<maven.compiler.release>10</maven.compiler.release>
|
||||
<lombok.version>edge-SNAPSHOT</lombok.version>
|
||||
<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>${lombok.version}</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>
|
||||
<defaultGoal>clean compile exec:java</defaultGoal>
|
||||
<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>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</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,27 @@
|
|||
package pp;
|
||||
|
||||
/*-
|
||||
|
||||
package main
|
||||
import "fmt"
|
||||
func tasker (o, r chan int, d chan bool) {
|
||||
o <- 1; o <- 2
|
||||
fmt.Println (<-r); d <- true
|
||||
}
|
||||
func add (o, r chan int) {
|
||||
r <- ((<-o) + (<-o))
|
||||
}
|
||||
func main () {
|
||||
operand, result := make(chan int), make(chan int)
|
||||
done:= make(chan bool)
|
||||
go tasker (operand, result, done)
|
||||
go add (operand, result)
|
||||
<-done
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
public class Sum {
|
||||
public static void main(String... args) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Laboraufgabe "CSP mit Java-Mitteln"
|
||||
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/10-01-Rendezvous.html)
|
||||
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/10-Solutions.html#laboraufgabe-csp-mit-java-mitteln)
|
||||
|
||||
# Materialien
|
||||
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/10-csp.html)
|
||||
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/i10-csp.html)
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<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.10.01.Rendezvous_solution</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<exec.mainClass>pp.Sum</exec.mainClass>
|
||||
<maven.compiler.release>10</maven.compiler.release>
|
||||
<lombok.version>edge-SNAPSHOT</lombok.version>
|
||||
<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>${lombok.version}</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>
|
||||
<defaultGoal>clean compile exec:java</defaultGoal>
|
||||
<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>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</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,56 @@
|
|||
package pp;
|
||||
|
||||
/*-
|
||||
|
||||
package main
|
||||
import "fmt"
|
||||
func tasker (o, r chan int, d chan bool) {
|
||||
o <- 1; o <- 2
|
||||
fmt.Println (<-r); d <- true
|
||||
}
|
||||
func add (o, r chan int) {
|
||||
r <- ((<-o) + (<-o))
|
||||
}
|
||||
func main () {
|
||||
operand, result := make(chan int), make(chan int)
|
||||
done:= make(chan bool)
|
||||
go tasker (operand, result, done)
|
||||
go add (operand, result)
|
||||
<-done
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
public class Sum {
|
||||
static void tasker(int x, int y, BlockingQueue<Integer> o,
|
||||
BlockingQueue<Integer> r, BlockingQueue<Boolean> d) {
|
||||
o.offer(x);
|
||||
o.offer(y);
|
||||
try {
|
||||
System.out.println(r.take());
|
||||
d.put(true);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
static void add(BlockingQueue<Integer> o, BlockingQueue<Integer> r) {
|
||||
try {
|
||||
r.put(o.take() + o.take());
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String... args) throws InterruptedException {
|
||||
var operand = new LinkedBlockingQueue<Integer>();
|
||||
var result = new LinkedBlockingQueue<Integer>();
|
||||
var done = new LinkedBlockingQueue<Boolean>();
|
||||
(new Thread(() -> tasker(1, 2, operand, result, done))).start();
|
||||
(new Thread(() -> add(operand, result))).start();
|
||||
done.take();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Laboraufgabe "Logging in Multi-Threadumgebungen"
|
||||
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/10-02-Logger.html)
|
||||
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/10-Solutions.html#laboraufgabe-logging-in-multi-threadumgebungen)
|
||||
|
||||
# Materialien
|
||||
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/10-csp.html)
|
||||
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/i10-csp.html)
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<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.10.02.Logger</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.release>19</maven.compiler.release>
|
||||
<lombok.version>edge-SNAPSHOT</lombok.version>
|
||||
<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>${lombok.version}</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>
|
||||
<defaultGoal>clean compile</defaultGoal>
|
||||
<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>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</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,20 @@
|
|||
package pp;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
public interface Logging {
|
||||
public enum Severity {
|
||||
Debug, Info, Notice, Warning, Error, Critical, Alert, Emergency;
|
||||
}
|
||||
|
||||
void log(Severity level, String msg);
|
||||
|
||||
void flush();
|
||||
|
||||
void setPrintStream(PrintStream out);
|
||||
|
||||
void setSeverityLevel(Severity level);
|
||||
|
||||
Severity getSeverityLevel();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package pp;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
final class QueuedLogger extends Thread implements Logging {
|
||||
|
||||
private final Logging logger;
|
||||
|
||||
// ... TODO: BlockingQueues deklarieren ...
|
||||
|
||||
public QueuedLogger() {
|
||||
logger = null; // ... TODO: initialisieren ...
|
||||
// ... TODO: BlockingQueues initialisieren ...
|
||||
setDaemon(true);
|
||||
setPriority(Thread.MIN_PRIORITY);
|
||||
start(); // hier kein Problem, da Klasse final (s. pp.01.01-Inheritance)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
// ... TODO: BlockingQueues auswerten und loggen ...
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Severity level, String msg) {
|
||||
switch (level) {
|
||||
case Debug:
|
||||
// ... TODO: Blocking Queue befüllen ...
|
||||
case Info:
|
||||
// ... TODO: Blocking Queue befüllen ...
|
||||
case Notice:
|
||||
// ... TODO: Blocking Queue befüllen ...
|
||||
case Warning:
|
||||
// ... TODO: Blocking Queue befüllen ...
|
||||
case Error:
|
||||
// ... TODO: Blocking Queue befüllen ...
|
||||
case Critical:
|
||||
// ... TODO: Blocking Queue befüllen ...
|
||||
case Alert:
|
||||
// ... TODO: Blocking Queue befüllen ...
|
||||
case Emergency:
|
||||
// ... TODO: Blocking Queue befüllen ...
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
logger.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeverityLevel(Severity level) {
|
||||
logger.setSeverityLevel(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Severity getSeverityLevel() {
|
||||
return logger.getSeverityLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintStream(PrintStream out) {
|
||||
logger.setPrintStream(out);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package pp;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class SimpleLoggerSafe implements Logging, AutoCloseable {
|
||||
public SimpleLoggerSafe() {
|
||||
// ... TODO ...
|
||||
}
|
||||
|
||||
public SimpleLoggerSafe(Severity level) {
|
||||
// ... TODO ...
|
||||
}
|
||||
|
||||
public SimpleLoggerSafe(Severity level, PrintStream out) {
|
||||
// ... TODO ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
// ... TODO ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Severity level, String msg) {
|
||||
// ... TODO ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
// ... TODO ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeverityLevel(Severity level) {
|
||||
// ... TODO ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintStream(PrintStream out) {
|
||||
// ... TODO ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public Severity getSeverityLevel() {
|
||||
// ... TODO ...
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package pp;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class SimpleLoggerUnsafe implements Logging, AutoCloseable {
|
||||
private static final int CAPACITY = 1024;
|
||||
private final StringBuilder log = new StringBuilder(CAPACITY);
|
||||
private Severity level;
|
||||
private PrintStream out;
|
||||
|
||||
public SimpleLoggerUnsafe() {
|
||||
setSeverityLevel(Logging.Severity.Warning);
|
||||
setPrintStream(System.err);
|
||||
}
|
||||
|
||||
public SimpleLoggerUnsafe(Severity level) {
|
||||
this();
|
||||
setSeverityLevel(level);
|
||||
}
|
||||
|
||||
public SimpleLoggerUnsafe(Severity level, PrintStream out) {
|
||||
this(level);
|
||||
setPrintStream(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Severity level, String msg) {
|
||||
if (this.level.ordinal() <= level.ordinal()) {
|
||||
if ((this.log.length() + msg.length() //
|
||||
+ System.lineSeparator().length()) >= log.capacity()) {
|
||||
flush();
|
||||
}
|
||||
this.log.append(msg).append(System.lineSeparator());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
if (this.log.length() > 0) {
|
||||
this.out.print(this.log);
|
||||
this.out.flush();
|
||||
this.log.setLength(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeverityLevel(Severity level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintStream(PrintStream out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Severity getSeverityLevel() {
|
||||
return this.level;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package pp;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class ThreadLocalLogger implements Logging {
|
||||
|
||||
private ThreadLocal<Logging> logger = ThreadLocal.withInitial(() -> {
|
||||
// hier programmieren und ein ThreadLocal<Logging> statt null
|
||||
// zurückgeben
|
||||
return null;
|
||||
});
|
||||
|
||||
@Override
|
||||
public void log(Severity level, String msg) {
|
||||
logger.get().log(level, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
logger.get().flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeverityLevel(Severity level) {
|
||||
logger.get().setSeverityLevel(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Severity getSeverityLevel() {
|
||||
return logger.get().getSeverityLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintStream(PrintStream out) {
|
||||
logger.get().setPrintStream(out);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Laboraufgabe "Logging in Multi-Threadumgebungen"
|
||||
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/10-02-Logger.html)
|
||||
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/10-Solutions.html#laboraufgabe-logging-in-multi-threadumgebungen)
|
||||
|
||||
# Materialien
|
||||
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/10-csp.html)
|
||||
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/i10-csp.html)
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<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.10.02.Logger_solution</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.release>19</maven.compiler.release>
|
||||
<lombok.version>edge-SNAPSHOT</lombok.version>
|
||||
<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>${lombok.version}</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>
|
||||
<defaultGoal>clean compile</defaultGoal>
|
||||
<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>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</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,20 @@
|
|||
package pp;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
public interface Logging {
|
||||
public enum Severity {
|
||||
Debug, Info, Notice, Warning, Error, Critical, Alert, Emergency;
|
||||
}
|
||||
|
||||
void log(Severity level, String msg);
|
||||
|
||||
void flush();
|
||||
|
||||
void setPrintStream(PrintStream out);
|
||||
|
||||
void setSeverityLevel(Severity level);
|
||||
|
||||
Severity getSeverityLevel();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package pp;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
final class QueuedLogger extends Thread implements Logging {
|
||||
private final Logging logger;
|
||||
private final BlockingQueue<String> queueDebug;
|
||||
private final BlockingQueue<String> queueInfo;
|
||||
private final BlockingQueue<String> queueNotice;
|
||||
private final BlockingQueue<String> queueWarning;
|
||||
private final BlockingQueue<String> queueError;
|
||||
private final BlockingQueue<String> queueCritical;
|
||||
private final BlockingQueue<String> queueAlert;
|
||||
private final BlockingQueue<String> queueEmergency;
|
||||
|
||||
public QueuedLogger() {
|
||||
logger = new SimpleLoggerUnsafe();
|
||||
queueDebug = new LinkedBlockingQueue<>();
|
||||
queueInfo = new LinkedBlockingQueue<>();
|
||||
queueNotice = new LinkedBlockingQueue<>();
|
||||
queueWarning = new LinkedBlockingQueue<>();
|
||||
queueError = new LinkedBlockingQueue<>();
|
||||
queueCritical = new LinkedBlockingQueue<>();
|
||||
queueAlert = new LinkedBlockingQueue<>();
|
||||
queueEmergency = new LinkedBlockingQueue<>();
|
||||
setDaemon(true);
|
||||
setPriority(Thread.MIN_PRIORITY);
|
||||
start(); // hier kein Problem, da Klasse final (s. pp.01.01-Inheritance)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
var msg = "";
|
||||
if ((msg = this.queueEmergency.poll()) != null) {
|
||||
logger.log(Severity.Emergency, msg);
|
||||
} else if ((msg = this.queueAlert.poll()) != null) {
|
||||
logger.log(Severity.Alert, msg);
|
||||
} else if ((msg = this.queueCritical.poll()) != null) {
|
||||
logger.log(Severity.Critical, msg);
|
||||
} else if ((msg = this.queueError.poll()) != null) {
|
||||
logger.log(Severity.Error, msg);
|
||||
} else if ((msg = this.queueWarning.poll()) != null) {
|
||||
logger.log(Severity.Warning, msg);
|
||||
} else if ((msg = this.queueNotice.poll()) != null) {
|
||||
logger.log(Severity.Notice, msg);
|
||||
} else if ((msg = this.queueInfo.poll()) != null) {
|
||||
logger.log(Severity.Info, msg);
|
||||
} else if ((msg = this.queueDebug.poll()) != null) {
|
||||
logger.log(Severity.Debug, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Severity level, String msg) {
|
||||
if (logger.getSeverityLevel().ordinal() <= level.ordinal()) {
|
||||
var success = false;
|
||||
while (!success) { // falls die jeweilige Queue schon voll ist
|
||||
// (success == false) nochmal probieren
|
||||
switch (level) {
|
||||
case Debug:
|
||||
success = this.queueDebug.offer(msg);
|
||||
case Info:
|
||||
success = this.queueInfo.offer(msg);
|
||||
case Notice:
|
||||
success = this.queueNotice.offer(msg);
|
||||
case Warning:
|
||||
success = this.queueWarning.offer(msg);
|
||||
case Error:
|
||||
success = this.queueError.offer(msg);
|
||||
case Critical:
|
||||
success = this.queueCritical.offer(msg);
|
||||
case Alert:
|
||||
success = this.queueAlert.offer(msg);
|
||||
case Emergency:
|
||||
success = this.queueEmergency.offer(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
logger.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeverityLevel(Severity level) {
|
||||
logger.setSeverityLevel(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Severity getSeverityLevel() {
|
||||
return logger.getSeverityLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintStream(PrintStream out) {
|
||||
logger.setPrintStream(out);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package pp;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class SimpleLoggerSafe extends SimpleLoggerUnsafe
|
||||
implements Logging, AutoCloseable {
|
||||
|
||||
public SimpleLoggerSafe() {
|
||||
super();
|
||||
}
|
||||
|
||||
public SimpleLoggerSafe(Severity level) {
|
||||
super(level);
|
||||
}
|
||||
|
||||
public SimpleLoggerSafe(Severity level, PrintStream out) {
|
||||
super(level, out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void log(Severity level, String msg) {
|
||||
super.log(level, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void flush() {
|
||||
super.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setSeverityLevel(Severity level) {
|
||||
super.setSeverityLevel(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setPrintStream(PrintStream out) {
|
||||
super.setPrintStream(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() throws Exception {
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Severity getSeverityLevel() {
|
||||
return super.getSeverityLevel();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package pp;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class SimpleLoggerUnsafe implements Logging, AutoCloseable {
|
||||
private static final int CAPACITY = 1024;
|
||||
private final StringBuilder log = new StringBuilder(CAPACITY);
|
||||
private Severity level;
|
||||
private PrintStream out;
|
||||
|
||||
public SimpleLoggerUnsafe() {
|
||||
setSeverityLevel(Logging.Severity.Warning);
|
||||
setPrintStream(System.err);
|
||||
}
|
||||
|
||||
public SimpleLoggerUnsafe(Severity level) {
|
||||
this();
|
||||
setSeverityLevel(level);
|
||||
}
|
||||
|
||||
public SimpleLoggerUnsafe(Severity level, PrintStream out) {
|
||||
this(level);
|
||||
setPrintStream(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Severity level, String msg) {
|
||||
if (this.level.ordinal() <= level.ordinal()) {
|
||||
if ((this.log.length() + msg.length() //
|
||||
+ System.lineSeparator().length()) >= log.capacity()) {
|
||||
flush();
|
||||
}
|
||||
this.log.append(msg).append(System.lineSeparator());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
if (this.log.length() > 0) {
|
||||
this.out.print(this.log);
|
||||
this.out.flush();
|
||||
this.log.setLength(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeverityLevel(Severity level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintStream(PrintStream out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Severity getSeverityLevel() {
|
||||
return this.level;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package pp;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import javax.naming.OperationNotSupportedException;
|
||||
|
||||
public class ThreadLocalLogger implements Logging {
|
||||
|
||||
private ThreadLocal<Logging> logger = ThreadLocal.withInitial(() -> {
|
||||
PrintStream out = null;
|
||||
try {
|
||||
// jeder Thread bekommt garantiert seinen eigenen PrintStream
|
||||
out = new PrintStream(Thread.currentThread().threadId() + ".log");
|
||||
} catch (FileNotFoundException e) {
|
||||
// Abbruch mit Runtime statt Checked Exception:
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new SimpleLoggerUnsafe(Logging.Severity.Warning, out);
|
||||
});
|
||||
|
||||
@Override
|
||||
public void log(Severity level, String msg) {
|
||||
logger.get().log(level, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
logger.get().flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeverityLevel(Severity level) {
|
||||
logger.get().setSeverityLevel(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Severity getSeverityLevel() {
|
||||
return logger.get().getSeverityLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintStream(PrintStream out) {
|
||||
// Threads könnten denselben PrintStream verwenden. Damit das nicht
|
||||
// passiert, wird diese Methode "abgeschaltet".
|
||||
throw new RuntimeException(new OperationNotSupportedException());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue