diff --git a/website/assignments/Concurrency.md b/website/assignments/Concurrency.md new file mode 100644 index 0000000000000000000000000000000000000000..12ca0297b180c1b4d6234d92f37592d31ed665d9 --- /dev/null +++ b/website/assignments/Concurrency.md @@ -0,0 +1,17 @@ +# Ãœbungen Software-Entwicklung 3: Parallele Programmierung + +## Ausgangslage +In der Vorlesungen haben wir besprochen, wie Sie Teile Ihrer Anwendung parallelisieren können. Bei der Umsetzung müssen jedoch einige Dinge beachtet werden, insbesondere wenn auf _shared state_, sprich Variablen und Objekte, die von mehreren Threads gleichzeitig verarbeitet werden, zugegriffen wird. + +## Aufgabe +* Ãœberlegen Sie sich, welche Teile Ihrer Anwendung parallelisierbar sind. Kann dadurch Wartezeit verhindert oder währenddessen andere Aufgaben abgearbeitet werden? Gibt es Hintergrundaufgaben? +* Identifizieren Sie _shared state_ und überlegen sich wie Sie diesen schützen können. Dokumentieren Sie dies. +* Nutzen Sie geeignete Mittel, damit es weder zu Konsistenzproblemen (z.B. _lost update_) noch zu Programmflussproblemen (z.B. _dead lock_) kommt. +* Setzen Sie mindestens einen Anwendungsfall für parallele Programmierung inkl. Schutmaßnahmen in Ihrem Projekt vollständig um. + +## Tipps +* Nutzen Sie `log`-Ausgaben um das Verhalten Ihrer Threads zur Laufzeit nachvollziehen zu können. +* `ParallelStream`s können in Java eine Möglichkeit sein, große Datenmengen effektiv zu verarbeiten. + +## Ziele +* Ihr Projekt besitzt nebenläufige Programmanteile, die gegen die besprochenen Concurrency-Probleme geschützt sind. \ No newline at end of file diff --git a/website/assignments/bewertungsbogen.xlsx b/website/assignments/bewertungsbogen.xlsx index 1936851b814da32e84308bccbb79fd9641006984..5865010136be66a79a6aad33b1c4122ce7c2441e 100644 Binary files a/website/assignments/bewertungsbogen.xlsx and b/website/assignments/bewertungsbogen.xlsx differ diff --git a/website/concurrency.html b/website/concurrency.html index 65094a3ec77bee007e0b476e365881e49d993059..245efaf455a44f3cef9980ca823d4dd2b298db20 100644 --- a/website/concurrency.html +++ b/website/concurrency.html @@ -94,320 +94,228 @@ class: center, middle, first 1. Recap 2. Parallele Programmierung -3. https://www.vogella.com/tutorials/JavaConcurrency/article.html -4. https://www.baeldung.com/java-concurrency - -* Warum wird parallele Programmierung benötigt? -* Prozesse <-> Threads -* Amdahls Law -* Wie funktioniert parallele Programmierung? -* Wie funktioniert parallele Programmierung in Java? - * `Thread` - * `Runnable` - * `wait()`, `join()`, `notify()` - * `volatile` - * `Executor`-Framework -* Probleme bei paralleler Programmierung - * `shared state` - * Lost Update/Race conditions/Dirty Read - * Dead Lock -> https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html -* Möglichkeiten, Concurrency-Probleme in Java zu beheben - * Locks/Monitor-Objekte/`synchronized` - * `Atmoic`-Klassen - * `Concurrent`-Collections - * `Future`s, `Callable` - * Funktionale Programmierung -> Java Streams - * Was bedeutet funktionale Programmierung? -* Was ist Skalierung? Horizontale Skalierung <-> vertikale Skalierung --- # Recap: Was haben wir in der letzten Vorlesung besprochen? -* SQL -* NoSQL +* Client-/Server-Kommunikation +* Synchrone & asynchrone Schnittstellen +* REST-APIs + > Blick ins [Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt) --- class: center, middle -# Welche Formen der Kommunikationsbeziehungen kennen Sie in der (objektorientierten) Programmierung? +# Warum und wofür wird parallele Programmierung benötigt? --- -# Kommunikationsbeziehungen +# Prozesse <-> Threads -Beispiele: +## Prozess +* Eigener Speicherbereich +* Schwergewichtig +* Wird vom Betriebssystem verwaltet -* lokale Schnittstellen - * API (lokal) -* Remote Schnittstellen - * RPC - * RESTful-APIs - * SOAP-APIs - * Messaging-APIs/Event-based APIs +## Thread +* "Leichtgewichtiger Prozess" +* Programmteil, der parallel ausgeführt werden kann +* Wird aus einem Prozess heraus gestartet +* Kann auf Speicherbereich anderer Threads zugreifen --- -# Gruppierung der Schnittstellenarten - -## Synchrone Schnittstellen +# Amdahls Law -## Asynchrone Schnittstellen - ---- -# Definition synchrone Schnittstelle +> Anwendungen lassen sich **nicht** unendlich durch Parallelisierung beschleunigen -> Der Sender **blockiert** bis vom Empfänger eine Antwort geschickt wurde. +**Ursachen**: -## Beispiele für synchrone Kommunikation - -* HTTP -* SOAP -* GraphQL -* RPC (z.B. RMI, gRPC) -* REST - ---- +* Programmanteile, die synchron ablaufen müssen +* Verwaltungsaufwand (-> Overhead) steigt mit steigender Anzahl CPUs/Prozesse/Threads -# Ablauf synchrone Schnittstelle (vereinfacht) +<img src="img/concurrency/Amdahl.png" alt="Amdahl's Law" width="30%"> -## Sender -1. Verfassen einer Nachricht -2. Verpacken der Nachricht (_Marshalling_) -3. Absenden der Nachricht -4. _Warten auf Antwort_ -5. Empfangen der Antwort-Nachricht -6. Auspacken der Antwort-Nachricht -7. Verarbeiten der Antwort-Nachricht +_Quelle: Frank Klemm, 2017, [Wikipedia](https://commons.wikimedia.org/wiki/File:Amdahl.png), [Creative Commons Share Alike](https://creativecommons.org/licenses/by-sa/4.0/deed.en)_ --- -# Ablauf synchrone Schnittstelle (vereinfacht) +# Schritte der parallelen Programmierung -## Empfänger -1. _Warten auf eingehende Nachrichten_ -2. Empfangen der Nachricht -3. Auspacken der Nachricht -4. Verarbeiten der Nachricht -5. Verfassen der Antwort-Nachricht -6. Verpacken der Antwort-Nachricht -7. Verschicken der Antwort-Nachricht +1. Identifikation des parallellaufenden Anteils +2. Herauslösen und auslagern des parallellaufenden Anteils +3. Starten des parallelen Anteils +4. Ggf. zusammenführen mit anderen Programmteilen --- -# Ablauf synchrone Schnittstelle +# Schritte der parallelen Programmierung mit Java-`Threads` (I) -**Neu!** +* Identifikation des parallellaufenden Anteils +* Herauslösen und auslagern des parallellaufenden Anteils in einen `Thread` -> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung) +```java +class MyThread extends Thread {...} ---- -# Was ist REST? +class MyRunnable implements Runnable {...} +``` -> REST: Representational State Transfer +* Implementieren der `run()`-Methode -Softwarearchitekturstil +```java +public void run(){ + // do stuff +} +``` --- -# Grundprinzipien - -_nach [Wikipedia, 2022](https://de.wikipedia.org/wiki/Representational_State_Transfer)_ - -* Client/Server -* Zustandslosigkeit -* Caching -* Einheitliche Schnittstelle - * Adressierbarkeit von Ressourcen - * Repräsentationen zur Veränderung von Ressourcen - * Selbstbeschreibende Nachrichten - * „Hypermedia as the Engine of Application State“ (HATEOAS) -* Mehrschichtige Systeme -* Code on Demand (optional) ---- -# REST-URIs +# Schritte der parallelen Programmierung mit Java-`Threads` (II) -> URI: Uniform Resource Identifier +* Starten des parallelen Anteils -> `Thread` & `start()` -Mögliche URI-Muster: -* `<protocol>://<service-name>/<resource-type>/<resource-id>` -* `<resource-type>/<resource-id>` -* `<protocol>://<service-name>/<resource-type>/<resource-id>/<resource-details>` -* `<protocol>://<service-name>/<api-version>/<resource-type>/<resource-id>` +```java +MyThread t0 = new MyThread(); +t0.start(); -Beispiele: -* `https://music-mamager.app/songs/112233` -* `https://music-mamager.app/songs/112233/play` -* `https://music-mamager.app/songs/112233/artist` -* `/v3/songs/112233/artist/json` +Thread t1 = new Thread(new MyRunnable()); +t1.start(); +``` ---- -# REST im Einsatz - -* Verwendung auf Basis von HTTP/HTTPS -* Nutzen der [HTTP-Verben](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) - * `POST` - * `GET` - * `DELETE` - * `PUT` (entspricht einem Update) - * ... -* Nutzen der HTTP-Status-Codes für Antworten - * [Ãœbersicht der HTTP-Status-Codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) +* Ggf. zusammenführen mit anderen Programmteilen +```java +t0.join(); +t1.join(); +``` --- -# REST-APIs mit OpenAPI 3/Swagger +# `volatile` -* API-Spezifikation -* API-Dokumentation -* API-Generierung -* Testumgebung - -[Petstore Demo Projekt](https://petstore.swagger.io/) - ---- -# REST mit Spring Boot (I) - -* Alternative zu `JAX-WS` -* Maven-Dependency hinzufügen (`spring-boot-starter-web`) - -```xml -<dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-web</artifactId> - <version>2.7.0</version> - <!-- ... --> -</dependency> +```java +private volatile int value = 10; ``` -* Erstellen einer Klasse, die mit `@RestController` annotiert wird -* Annotieren der Methoden mit geeigneter HTTP-Verb Annotation (z.B. `@GetMapping`) und zuweisen des Resource-Pfads (z.B. `/songs`) -* Mapping der URL-Parameter zu Java-Parametern mit der `@RequestParam(value = "name", defaultValue = "Song 2")` ---- -# REST mit Spring Boot (II) +* Garantiert dass alle Threads Änderungen an einer Variable umgehend mitbekommen +* Variable wird **nicht** von Threads gecacht -Start der Anwendung: +--- +# Thread-relevante Methoden (I) +## `join()` ```java -@SpringBootApplication -public class RestServiceApplication { - - public static void main(String[] args) { - SpringApplication.run(RestServiceApplication.class, args); - } - -} +Thread t0 = new Thread(); +... +t0.join(); // warten bis t0 fertig ist ``` --- -# REST mit Spring Boot (III) - -_Quelle: ["Building a RESTful Web Service", spring.io, 2022](https://spring.io/guides/gs/rest-service/)_ +# Thread-relevante Methoden (II) ```java -package com.example.restservice; - -public class Greeting { - - private final long id; - private final String content; - - public Greeting(long id, String content) { - this.id = id; - this.content = content; - } - - public long getId() { - return id; - } - - public String getContent() { - return content; - } +public class BlockingQueue<T> { + private Queue<T> queue = new LinkedList<T>(); + private int capacity; + + public BlockingQueue(int capacity) { + this.capacity = capacity; + } + public synchronized void put(T element) throws InterruptedException { + while(queue.size() == capacity) { + wait(); + } + + queue.add(element); + notify(); // notifyAll() for multiple producer/consumer threads + } + public synchronized T take() throws InterruptedException { + while(queue.isEmpty()) { + wait(); + } + T item = queue.remove(); + notify(); // notifyAll() for multiple producer/consumer threads + return item; + } } ``` - +_Quelle: https://stackoverflow.com/a/2537117_ --- -# REST mit Spring Boot (IV) +# `ExecutorService` ```java -package com.example.restservice; - -import java.util.concurrent.atomic.AtomicLong; +ExecutorService executor = Executors.newFixedThreadPool(10); + +Runnable runnableTask = () -> { + try { + TimeUnit.MILLISECONDS.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } +}; + +Callable<String> callableTask = () -> { + TimeUnit.MILLISECONDS.sleep(300); + return "Task's execution"; +}; + +executorService.execute(runnableTask); +Future<String> future = executorService.submit(callableTask); + +List<Callable<String>> callableTasks = new ArrayList<>(); +callableTasks.add(callableTask); +callableTasks.add(callableTask); +callableTasks.add(callableTask); + +List<Future<String>> futures = executorService.invokeAll(callableTasks); +String result = executorService.invokeAny(callableTasks); +``` +_Quelle: https://www.baeldung.com/java-executor-service-tutorial_ -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +--- +# Probleme bei paralleler Programmierung -@RestController -public class GreetingController { +> **Shared state!** - private static final String template = "Hello, %s!"; - private final AtomicLong counter = new AtomicLong(); +### Konsistenzprobleme +### Programmflussprobleme - @GetMapping("/greeting") - public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) { - return new Greeting(counter.incrementAndGet(), String.format(template, name)); - } -} -``` --- -# REST-Demo im Projekt +# Konsistenzprobleme -> Blick ins [Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt) +> Ungeschützer Zugriff aufgeteilte Ressourcen ---- -class: center, middle +* "Lost update" +* "Race condition" +* "Dirty read" -# Asynchrone Kommunikationsbeziehungen +> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung) --- -# Definition asynchrone Schnittstelle +# Programmflussprobleme -> Sender **blockiert nicht** bis vom Empfänger eine Antwort geschickt wurde. +> Gegenseitige Blockade parallellaufender Programmteile -## Beispiele asynchrone Kommunikation +## Dead lock -* Chats -* E-Mail -* Message Broker/Queues (implementierungsabhängig) +* Ãœberkreuzzugriff auf Locks ---- -# Message Broker +> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung) -_nach: "Learn Microservices with Spring Boot", Moisés Macero GarcÃa, apress, 2020, S. 216_ +--- +# Möglichkeiten, Concurrency-Probleme in Java zu beheben -<img alt="Schematische Darstellung Message Broker" src="img/schnittstellen/message_broker.png" width="100%"/> +* Locks/Monitor-Objekte/`synchronized` +* `Atmoic`-Klassen +* `Concurrent`-Collections +* Funktionale Programmierung -> Java Streams + +> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung) --- -# Ablauf asynchrone Schnittstelle (vereinfacht) +# Skalierung -## Sender -1. Verfassen einer Nachricht -2. Verpacken der Nachricht (_Marshalling_) -3. Absenden der Nachricht -4. _Weiter im Programmfluss_ -5. _Ggf. Empfangen der Antwort-Nachricht (nach Zeitraum X)_ -6. _Ggf. Auspacken der Antwort-Nachricht_ -7. _Ggf. Verarbeiten der Antwort-Nachricht_ +## Vertikale Skalierung ---- -# Ablauf asynchrone Schnittstelle (vereinfacht) +> Erhöhung der Hardwareressourcen einer Maschine -## Empfänger -1. _Warten auf eingehende Nachrichten_ -2. Empfangen der Nachricht -3. Auspacken der Nachricht -4. Verarbeiten der Nachricht -5. _Ggf. Verfassen der Antwort-Nachricht_ -6. _Ggf. Verpacken der Antwort-Nachricht_ -7. _Ggf. Verschicken der Antwort-Nachricht_ +## Horizontale Skalierung ---- -# Backup Themen: Software im Betrieb - -* Eventual consistency -* Monitoring -* Logging -* Security -* Patching -* Releaseplanung -* Downtimes -* Dokumentation/Schulungen +> Erhöhen der Maschinenanzahl </textarea> <script src="js/remark.min.js"> diff --git a/website/img/concurrency/Amdahl.png b/website/img/concurrency/Amdahl.png new file mode 100644 index 0000000000000000000000000000000000000000..5b255e2620c314eda26eafe84621dd5a1957cc4e Binary files /dev/null and b/website/img/concurrency/Amdahl.png differ diff --git a/website/index.html b/website/index.html index a6d4499de79c7f4b2deaa29088adeaaa3ddafdda..0af7d67aaaf4bde3b987737352ac4c314afc8049 100644 --- a/website/index.html +++ b/website/index.html @@ -18,6 +18,7 @@ <li><a href="container-ci-cd.html" target="_blank">Container & CI/CD</a></li> <li><a href="sql-nosql.html" target="_blank">SQL, NoSQL</a></li> <li><a href="schnittstellen.html" target="_blank">Schnittstellen</a></li> + <li><a href="concurrency.html" target="_blank">Parallele Programmierung</a></li> </ul> <h3>Vorlesungnotizen</h3> @@ -29,6 +30,7 @@ <li><a href="https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung/-/blob/main/website/lecturenotes/20220509.md" target="_blank">Vorlesungsnotizen - 09.05.2022</a></li> <li><a href="https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung/-/blob/main/website/lecturenotes/20220516.md" target="_blank">Vorlesungsnotizen - 16.05.2022</a></li> <li><a href="https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung/-/blob/main/website/lecturenotes/20220523.md" target="_blank">Vorlesungsnotizen - 23.05.2022</a></li> + <li><a href="https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung/-/blob/main/website/lecturenotes/20220523.md" target="_blank">Vorlesungsnotizen - 13.06.2022</a></li> </ul> <h3>Projekt</h3> @@ -45,6 +47,7 @@ <li><a href="https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung/-/blob/main/website/assignments/Container-CI_CD.md" target="_blank">Ãœbung: Container & CI/CD</a> </li> <li><a href="https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung/-/blob/main/website/assignments/sql-nosql.md" target="_blank">Ãœbung: SQL, NoSQL</a> </li> <li><a href="https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung/-/blob/main/website/assignments/Schnittstellen.md" target="_blank">Ãœbung: Schnittstellen</a> </li> + <li><a href="https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung/-/blob/main/website/assignments/Schnittstellen.md" target="_blank">Ãœbung: Parallele Programmierung</a> </li> </ul> <h3>Organisatorisches</h3> diff --git a/website/lecturenotes/20220613.md b/website/lecturenotes/20220613.md new file mode 100644 index 0000000000000000000000000000000000000000..203f9d2eeea8738a4057a599cec3539b3dda3b17 --- /dev/null +++ b/website/lecturenotes/20220613.md @@ -0,0 +1,4 @@ +# Vorlesungsnotizen - 13.06.2022 + +## Parallele Programmierung +