-
Jordine Tobias Dr. authoredJordine Tobias Dr. authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
concurrency.html 9.79 KiB
<!DOCTYPE html>
<html>
<head>
<title>Parallele Programmierung</title>
<meta charset="utf-8">
<link href="css/hdm.css" rel="stylesheet"></link>
<style>
/* yanone-kaffeesatz-regular - latin */
@font-face {
font-family: 'Yanone Kaffeesatz';
font-style: normal;
font-weight: 400;
src: url('fonts/yanone-kaffeesatz-v22-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/yanone-kaffeesatz-v22-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/yanone-kaffeesatz-v22-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/yanone-kaffeesatz-v22-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/yanone-kaffeesatz-v22-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/yanone-kaffeesatz-v22-latin-regular.svg#YanoneKaffeesatz') format('svg'); /* Legacy iOS */
}
/* noto-serif-regular - latin */
@font-face {
font-family: 'Noto Serif';
font-style: normal;
font-weight: 400;
src: url('fonts/noto-serif-v20-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/noto-serif-v20-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/noto-serif-v20-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/noto-serif-v20-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/noto-serif-v20-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/noto-serif-v20-latin-regular.svg#NotoSerif') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-regular - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: normal;
font-weight: 400;
src: url('fonts/ubuntu-mono-v14-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-regular.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-italic - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: italic;
font-weight: 400;
src: url('fonts/ubuntu-mono-v14-latin-italic.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-italic.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-italic.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-italic.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-700 - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: normal;
font-weight: 700;
src: url('fonts/ubuntu-mono-v14-latin-700.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-700.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-700.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
body { font-family: 'Noto Serif'; }
h1, h2, h3 {
font-family: 'Yanone Kaffeesatz';
font-weight: normal;
}
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
</style>
</head>
<body>
<textarea id="source">
class: center, middle, first
# Software-Entwicklung 3
## Parallele Programmierung
---
# Agenda
1. Recap
2. Parallele Programmierung
---
# Recap: Was haben wir in der letzten Vorlesung besprochen?
* Client-/Server-Kommunikation
* Synchrone & asynchrone Schnittstellen
* REST-APIs
> Blick ins [Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
---
class: center, middle
# Warum und wofür wird parallele Programmierung benötigt?
---
# Prozesse <-> Threads
## Prozess
* Eigener Speicherbereich
* Schwergewichtig
* Wird vom Betriebssystem verwaltet
## Thread
* "Leichtgewichtiger Prozess"
* Programmteil, der parallel ausgeführt werden kann
* Wird aus einem Prozess heraus gestartet
* Kann auf Speicherbereich anderer Threads zugreifen
---
# Amdahls Law
> Anwendungen lassen sich **nicht** unendlich durch Parallelisierung beschleunigen
**Ursachen**:
* Programmanteile, die synchron ablaufen müssen
* Verwaltungsaufwand (-> Overhead) steigt mit steigender Anzahl CPUs/Prozesse/Threads
<img src="img/concurrency/Amdahl.png" alt="Amdahl's Law" width="30%">
_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)_
---
# Schritte der parallelen Programmierung
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
---
# Schritte der parallelen Programmierung mit Java-`Threads` (I)
* Identifikation des parallellaufenden Anteils
* Herauslösen und auslagern des parallellaufenden Anteils in einen `Thread`
```java
class MyThread extends Thread {...}
class MyRunnable implements Runnable {...}
```
* Implementieren der `run()`-Methode
```java
public void run(){
// do stuff
}
```
---
# Schritte der parallelen Programmierung mit Java-`Threads` (II)
* Starten des parallelen Anteils -> `Thread` & `start()`
```java
MyThread t0 = new MyThread();
t0.start();
Thread t1 = new Thread(new MyRunnable());
t1.start();
```
* Ggf. zusammenführen mit anderen Programmteilen
```java
t0.join();
t1.join();
```
---
# `volatile`
```java
private volatile int value = 10;
```
* Garantiert dass alle Threads Änderungen an einer Variable umgehend mitbekommen
* Variable wird **nicht** von Threads gecacht
---
# Thread-relevante Methoden (I)
## `join()`
```java
Thread t0 = new Thread();
...
t0.join(); // warten bis t0 fertig ist
```
---
# Thread-relevante Methoden (II)
```java
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_
---
# `ExecutorService`
```java
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_
---
# Probleme bei paralleler Programmierung
> **Shared state!**
### Konsistenzprobleme
### Programmflussprobleme
---
# Konsistenzprobleme
> Ungeschützer Zugriff aufgeteilte Ressourcen
* "Lost update"
* "Race condition"
* "Dirty read"
> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung)
---
# Programmflussprobleme
> Gegenseitige Blockade parallellaufender Programmteile
## Dead lock
* Überkreuzzugriff auf Locks
> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung)
---
# Möglichkeiten, Concurrency-Probleme in Java zu beheben
* Locks/Monitor-Objekte/`synchronized`
* `Atmoic`-Klassen
* `Concurrent`-Collections
* Funktionale Programmierung -> Java Streams
> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung)
---
# Skalierung
## Vertikale Skalierung
> Erhöhung der Hardwareressourcen einer Maschine
## Horizontale Skalierung
> Erhöhen der Maschinenanzahl
</textarea>
<script src="js/remark.min.js">
</script>
<script>
var slideshow = remark.create();
</script>
</body>
</html>