Benutzer-Werkzeuge

Webseiten-Werkzeuge


parallelism:start

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
parallelism:start [2024/12/20 07:46] – [Beispiel 2: Eigene Klasse, die Runnable implementiert] Martin Pabstparallelism:start [2025/05/02 08:05] (aktuell) – [Aufgabe 1: Arbeitsteiliges Abarbeiten einer Aufgabe durch mehrere Threads] Martin Pabst
Zeile 4: Zeile 4:
   * Von modernen Betriebssystemen wird erwartet, dass sie es ermöglichen, sehr viele Prozesse (meist mehr als Prozessorkerne verfügbar sind) gleichzeitig ablaufen zu lassen.   * Von modernen Betriebssystemen wird erwartet, dass sie es ermöglichen, sehr viele Prozesse (meist mehr als Prozessorkerne verfügbar sind) gleichzeitig ablaufen zu lassen.
  
-Welche Herausforderungen dies in der Softwartechnik zur Folge hat und wie die auftretenden Probleme gelöst werden können, erfahren Sie in diesem Kapitel.+Welche Herausforderungen dies in der Softwartechnik zur Folge hat und wie die auftretenden Probleme gelöst werden können, erfahren Sie in diesem Kapitel. \\ \\  
 +**Unterkapitel:** 
 +  * [[parallelism:monitor:start|Wechselseitiger Ausschluss]] 
 +  * [[parallelism:producerconsumer:start|Erzeuger-Verbraucher-Probleme]] 
 +  * [[parallelism:deadlocks:start|Deadlocks (Verklemmungen)]]
 </WRAP> </WRAP>
  
Zeile 94: Zeile 98:
  
  
-==== Für Interessierte: Implementierung eines Interfaces durch eine Lambda-Function ====+===== Die Methode join =====
 <WRAP center round info 60%> <WRAP center round info 60%>
 +Ruft man während der Abarbeitung eines Threads (im folgenden: "Thread 1") die Methode ''join'' eines **anderen** Threads (im folgenden: "Thread 2") auf, so wartet Thread 1 so lange, bis Thread 2 beendet ist. Erst dann fährt Thread 1 mit der nächsten Anweisung fort. \\ \\
 +**Wichtiges Detail:** \\  
 +Das "Warten" von Thread 1 geschieht nicht **aktiv**, indem in einer Wiederholung immer wieder überprüft wird, ob Thread 2 schon beendet ist, sondern **passiv**, d.h. der für Thread 1 reservierte Prozessorkern steht in dieser Zeit für andere Threads zur Verfügung: 
 +</WRAP>
 +
 +==== Beispiel 3: Nutzung von Thread.join ====
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 400px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Threads1a'}">
 +
 +<script type="text/plain" title="Hauptprogramm.java">
 +SystemTools.setSpeed(8);
 +ArrayList<Thread> threads = new ArrayList<>();
 +
 +for (int i = 0; i < 10; i++) {
 +   Thread t = new MyThread("Thread " + i);
 +   threads.add(t);
 +   t.start();
 +}
 +
 +for(Thread t: threads){
 +   t.join();
 +}
 +
 +println("Alle fertig!", Color.lightgreen);
 +
 +class MyThread extends Thread {
 +
 +   public void run() {
 +      int i = 0;
 +      while (i < 10) {
 +         i++;
 +         
 +         println(this.getName() + " counts:  " + i );
 +         
 +      }
 +   }
 +}
 +</script>
 +
 +</div>
 +</HTML>
 +
 +==== Aufgabe 1: Arbeitsteiliges Abarbeiten einer Aufgabe durch mehrere Threads ====
 +<WRAP center round todo 80%>
 +Im folgenden Programm wird die Summe aller Elemente eines Arrays ermittelt und ausgegeben. Die Abarbeitung dieser Aufgabe erfolgt in einem einzigen Thread. \\ \\ 
 +Schreiben Sie das Programm so um, dass 10 nebenläufige Threads je 1/10 der Werte addieren und nach Abarbeitung aller 10 Threads die Teilsummen zu einer Gesamtsumme zusammengefasst werden.
 +</WRAP>
 +<WRAP center round tip 80%>
 +**Wichtige Info zu dieser Aufgabe:** \\ 
 +Javascript-Programme im Browser unterliegen der Einschränkung, dass sie nur von einem Prozessor-Thread ausgeführt werden können. Die Online-IDE simuliert mehrere Threads durch einen eigenen Scheduler, der schnell zwischen den Threads "umschaltet". Dies bringt aber natürlich keinen Geschwindigkeitsvorteil. \\ 
 +Startet man in einer "echten" Java Runtime Engine mehrere Threads, so werden sie auf mehrere Prozessorkerne verteilt und erzielen damit i.d.R. einen erheblichen Geschwindigkeitsvorteil gegenüber einem einzelnen Thread.
 +</WRAP>
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 400px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'ThreadsArbeitsteiligVorlage'}">
 +
 +<script type="text/plain" title="Hauptprogramm.java">
 +int[] werte = new int[1000];
 +for (int i = 0; i < werte.length; i++) {
 +   werte[i] = Random.randint(-1000, 1000);
 +}
 +
 +println(new ArrayTool().summe(werte));
 +
 +class ArrayTool {
 +   
 +   int summe(int[] werte) {
 +      int summe = 0;
 +      for (int i = 0; i < werte.length; i++) {
 +         summe += werte[i];
 +      }
 +      
 +      return summe;
 +   }
 +
 +}
 +</script>
 +
 +</div>
 +</HTML>
 +
 +[[.arbeitsteiligLoesung:start|Lösung]]
 +
 +==== Für Interessierte: Implementierung eines Interfaces durch eine Lambda-Function (nicht klausurrelevant) ====
 +<WRAP center round info 80%>
 Besitzt ein Interface nur eine einzige Methode, so nennt man es **functional interface**. Das Interface ''Runnable'' ist ein Beispiel dafür. \\  Besitzt ein Interface nur eine einzige Methode, so nennt man es **functional interface**. Das Interface ''Runnable'' ist ein Beispiel dafür. \\ 
 An jeder Stelle, an der ein Objekt einer Klasse erwartet wird, die ein functional interface implementiert, kann stattdessen eine Kurzform verwendet werden, die man **lambda function** nennt. Sie sieht so aus: An jeder Stelle, an der ein Objekt einer Klasse erwartet wird, die ein functional interface implementiert, kann stattdessen eine Kurzform verwendet werden, die man **lambda function** nennt. Sie sieht so aus:
Zeile 101: Zeile 193:
 (parameter 1, ..., parameter n) -> { Anweisungen } (parameter 1, ..., parameter n) -> { Anweisungen }
 </code> </code>
 +Lambda functions sind ein Ersatz für die in vielen anderen Programmiersprachen verfügbaren **closures**, unterscheiden sich aber in einem wesentlichen Punkt von diesen: Wird eine **außerhalb** der lambda function/closure deklarierte Variable **innerhalb** der lambda function/closure genutzt, so wird  
 +  * im Falle der lambda function ihr Wert zum Zeitpunkt des Starts der Funktion übergeben während 
 +  * im Falle der closure eine Referenz übergeben wird.
 +Bei letzteren kann daher von verschiedenen closures und von außerhalb auf **die identische Variable** zugegriffen werden, während bei ersteren jede lambda function ihre eigene Kopie der Variable erhält und nur auf diese zugreifen kann.
 </WRAP> </WRAP>
 +
  
 <HTML> <HTML>
parallelism/start.1734680812.txt.gz · Zuletzt geändert: 2024/12/20 07:46 von Martin Pabst

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki