maybemali0757
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Prog2 [ToC] ## Chapter 01 - Überblick und Motivation ### Business Intelligence #### Definition BI: - Business Intelligence (BI) vereint Managementmethoden, IT-Prozesse und analytische Verfahren, um Daten aufzubereiten, relevante Muster zu erkennen und Erkenntnisse zur Unterstützung von Managemententscheidungen zu kommunizieren. Dabei werden speziell fortschrittliche Technologien wie Data Warehousing und Big Data eingesetzt. ### Nebenläufigkeit und Parallelität #### Was ist Moore's Gesetz? - Verdopplung der Transistoren auf Schaltkreisen ca. alle 18-24 Monate, was zu mehr Rechenleistung führt. #### Nebenläufigkeit (Concurrency) vs. Parallelität: ![1000005501](https://hackmd.io/_uploads/ryFyinCxC.jpg) - Nebenläufigkeit: Unabhängige Tasks werden "zeitlich durchmischt" ausgeführt, auch auf Einzelprozessorsystemen möglich. - Parallelität: Unabhängige Tasks werden gleichzeitig auf unterschiedlichen Prozessorkernen ausgeführt, nur auf Multiprozessorsystemen möglich. #### Multithreading vs. Multicore: ![image](https://hackmd.io/_uploads/rJakF3ClC.png) - Multithreading: Einzelne Programme werden in mehrere Threads aufgeteilt. - Multicore: Mehrere Prozessoren auf einem Chip für parallele Ausführung von Programmen. #### Was ist Bit-Level-Parallelität? - Erhöhung der Busbreite verringert Anzahl notwendiger Instruktionen. - z.B.: Addition von zwei 16-Bit-Integer-Werten -> zwei Instr. auf 8-Bit-Prozessor, aber nur 1 Instruktion auf 16-Bit-Prozessor #### Was bedeutet Instruction-Level-Parallelität? ![image](https://hackmd.io/_uploads/Synl23Al0.png) - Gleichzeitige Ausführung unabhängiger Anweisungen (Pipelining). #### Data vs. Task Parallelism: - Data Parallelism: Verteilung von Daten auf mehrere Knoten/Prozessoren. - Task Parallelism: Verteilung von Aufgaben auf mehrere Prozessoren. #### Shared-Memory vs. Distributed-Memory: - Shared-Memory: Alle Kerne haben Zugriff auf gemeinsamen Speicher. - Distributed-Memory: Jeder Prozessor hat eigenen Speicher. #### Mehrkernprozessoren: - Kostengünstiger und effizienter als mehrere Einkernprozessoren. #### Amdahls Gesetz: - Beschränkt Geschwindigkeitszuwachs bei Parallelverarbeitung durch sequentiellen Anteil der Programme. #### Klassische Nebenläufigkeitsmechanismen: - Threads und Scheduling, Thread-Sicherheit, kritische Bereiche. - Semaphore, Monitore, atomare Variablen. #### Imperative vs. deklarative Sprachen: - Imperative Sprachen: Anweisungen kontrollieren den Ablauf. - Deklarative Sprachen: Beschreibung des gewünschten Ergebnisses. #### Programmierparadigmen: - Objektorientierung vs. funktionale Programmierung: -- Objektorientierung nutzt Klassen und Vererbung. -- Funktionale Programmierung nutzt Funktionen und Unveränderlichkeit - Objektfunktionale Programmierung in Scala: -- Kombination von OOP und funktionalen Konzepten, reduziert Seiteneffekte. - Entwicklungsumgebungen und Tools: -- IntelliJ IDEA, REPLs, Jupyter Notebooks, Git, Gradle. #### Zusammenfassung: - In diesem Kapitel wird das Fundament für moderne Programmierparadigmen gelegt, indem sowohl die theoretischen Grundlagen als auch die praktischen Werkzeuge vorgestellt werden. - Das Verständnis der Nebenläufigkeit und Parallelität ist essentiell für die Entwicklung leistungsfähiger Anwendungen in heutigen und zukünftigen Multi-Core-Systemen. - Amdahls Gesetz gibt einen Rahmen für die Einschätzung der Effizienz von parallelen Systemen. - Die verschiedenen Programmierparadigmen und ihre Umsetzung in Java und Scala bereiten die Studierenden darauf vor, robuste und effiziente Software zu schreiben. #### Mögliche Prüfungsfragen: - Beschreiben Sie das Mooresche Gesetz und seine Auswirkungen auf die Entwicklung von Computerhardware. - - Das Mooresche Gesetz prognostizierteine Verdopplung der Transistoranzahl auf Mikrochips alle zwei Jahre, was zu kontinuierlichen Leistungssteigerungen der Computerhardware führt. - Erklären Sie den Unterschied zwischen Nebenläufigkeit und Parallelität in der Programmierung. - - Nebenläufigkeit ermöglicht das unabhängige Bearbeiten von Tasks auf Einzelprozessorsystemen, während Parallelität die gleichzeitige Ausführung von Tasks auf Multiprozessorsystemen bezeichnet. - Was sind Stärken und Schwächen der Task-Parallelität und Data-Parallelität? - - Task-Parallelität ist flexibel bei unterschiedlichen Aufgaben, aber komplex in der Koordination, während Data-Parallelität effizient große Datenmengen verarbeitet, aber bei ungleicher Datenverteilung ineffizient sein kann. - Was sind die Herausforderungen bei der Umsetzung von Multithreading und Multicore-Programmierung? - - Multithreading birgt Herausforderungen bei der Synchronisation und Datensicherheit, Multicore-Programmierung bei der effizienten Lastverteilung und Kommunikation zwischen den Kernen. - Wie beeinflusst das Amdahlsche Gesetz die Geschwindigkeit von parallelisierten Anwendungen? - - Das Amdahlsche Gesetz begrenzt den Geschwindigkeitsgewinn von parallelisierten Anwendungen durch den Anteil der Aufgaben, die nur sequenziell bearbeitet werden können. - Diskutieren Sie die Vor- und Nachteile von objektorientierter und funktionaler Programmierung. - - OOP fördert die Strukturierung und Wartbarkeit von Code, während funktionale Programmierung die Nebenläufigkeit und Fehlervermeidung durch Unveränderlichkeit verbessert. ### Wie funktioneirt der SCheuler intern Scheduler= Zeitablaufsteuert. left fest welche threads ablaufen und wie viel prozessorzeit sie kriegen ![image](https://hackmd.io/_uploads/SkIBtQZfC.png) ![image](https://hackmd.io/_uploads/rJOhtXWf0.png) Präemptives Scheduling: Thread mit höherer priorität wird als Erstes vom Scheduler ausgeführt gegenstück: Thread mit höherer Priorität erlaubt niedrigeren Threads zuerst Prioritätsscheduling: Ordnet einem Thread eine Priorität zu ![image](https://hackmd.io/_uploads/Sk795mWfA.png) First in first out: wenn mehrere prozesse mit derselben Priorität ausgeführt werden, wird das mit first "ready" first ausgeführt. Heap and Stack Memory Stack: ein Thread zugewiesener Stapelbereich mit Last In First Out bereich nur Zugriff auf das Doument, das ganz oben liegt Heap: ein Zugewiesener speicherbereich, verfügbar für alle Threads. zur ablge von objekten, klassen und isntanzvariablen referenzierung durch zeiger alles was im stack liegt, ist einem therad zugewiesen. jeder thread hat seinen excklusiven thread: kein thread zugriff salat. heap: alles muss geschützt werden. page 19 rafik lokale variablen: erhalten gültugkeit nur innerhalb er methode. danach gelöscht. instanzvariablen: werden instanziiert, wenn ein obj einer klasse instanziiert werden. klassenvaiablen: gehören zur klasse, nicht zum bestimmten obj. static. primitive variablen: variablen funktionieren wie datencontainer refernzvariablen verweisen auf die speicheradresse im Heap im stack: im heap: klassenvariablen. zeichenketten. stack und heap weiderholen. ![image](https://hackmd.io/_uploads/rkMsAQbf0.png) methodenaufruf: neuer aufruf im stack. Semaphore: Zählvariable. bestimte anzahl von threads ist es erlaubt in den kritischen bereich zu treten. wenn zählvariable 0, werden alle in Wartschlange geschickt. ![image](https://hackmd.io/_uploads/rJjKmE-M0.png) ## Chapter 02 - Nebenläufigkeit in Java ### Kapitel 2.1: Threads in Java #### Grundlagen - **Prozesse** vs. **Threads**: - Prozesse haben eigenen Adressraum und Ressourcen. - Threads teilen sich Ressourcen eines Prozesses und laufen nebenläufig. #### Threads in Java - Java verwendet die Klasse `java.lang.Thread` zur Repräsentation von Threads. - Lebenszyklus von Threads: - NEW: Instanz erstellt, nicht gestartet. - RUNNABLE: Bereit zur Ausführung. - RUNNING: Aktiv in Ausführung. - BLOCKED/WAITING: Wartet auf Ressourcen oder andere Threads. - TERMINATED: Beendet. #### Erzeugen von Threads - **Erzeugen durch Erweiterung der `Thread`-Klasse**: 1. Klasse erstellen, die `Thread` erweitert. 2. `run()` Methode überschreiben. 3. Instanz der Klasse erstellen. 4. `start()` Methode aufrufen, um Thread zu starten. - **Erzeugen durch Implementierung des `Runnable`-Interfaces**: 1. Klasse erstellt, die `Runnable` implementiert. 2. `run()` Methode überschreiben. 3. `Thread`-Objekt mit Instanz des `Runnable` erstellen. 4. `start()` Methode aufrufen. ![image](https://hackmd.io/_uploads/HJAj8wHGA.png) #### Thread-Methoden - Wichtige Methoden: `run()`, `start()`, `sleep()`, `join()`, `interrupt()`. - Zustandswechsel: - `sleep()` versetzt den Thread in den Zustand TIMED WAITING. - `join()` wartet, bis der angegebene Thread terminiert. #### Synchronisation und Thread-Sicherheit - Verhindert Race Conditions und gewährleistet korrekte Ausführung nebenläufiger Threads. - Mechanismen: - `synchronized` Schlüsselwort. - `wait()`, `notify()`, `notifyAll()` für koordiniertes Warten und Benachrichtigen. #### Zusammenfassung - Threads ermöglichen effiziente parallele Ausführung in Java. - Synchronisation ist entscheidend für die Sicherheit und Korrektheit in einem nebenläufigen Umfeld. ### Kapitel 2.2: Thread-Zustände und Scheduling ![image](https://hackmd.io/_uploads/BkTgdPHMR.png) #### Thread-Zustände - **Lebenszyklus eines Threads**: - **NEW**: Thread instanziert, aber nicht gestartet. - **RUNNABLE**: Bereit zur Ausführung, wartet auf Zuweisung einer CPU. - **RUNNING**: Aktiv und wird ausgeführt. - **BLOCKED**: Wartet auf eine Ressource. - **WAITING**: Wartet unbestimmt, bis eine Bedingung erfüllt ist. - **TIMED WAITING**: Wartet eine spezifizierte Zeit. - **TERMINATED**: Beendet und nicht mehr ausführbar. #### Scheduling - **Java Virtual Machine (JVM)**: - JVM Scheduling-Strategien sind abhängig von der Implementierung des Betriebssystems. - **Präemptives Scheduling** und **Prioritätsscheduling** sind gängige Strategien. - **Time Slicing** wird verwendet, um CPU-Zeit zwischen Threads aufzuteilen. #### Thread-Methoden und Zustandswechsel - **Wichtige Methoden**: - `sleep()`: Versetzt Thread in TIMED WAITING. - `join()`: Wartet auf Beendigung eines anderen Threads. - `yield()`: Gibt CPU freiwillig für andere Threads frei. - `interrupt()`: Unterbricht einen wartenden oder schlafenden Thread. #### Thread Prioritäten - Threads können Prioritäten zugewiesen werden, die das Scheduling beeinflussen. - Höher priorisierte Threads erhalten in der Regel mehr CPU-Zeit als niedriger priorisierte. #### Probleme bei Scheduling - **Race Conditions**: Mehrere Threads greifen gleichzeitig auf dieselbe Ressource zu. - **Deadlocks** und **Starvation** können auftreten, wenn Threads ineffizient verwaltet werden. #### Scheduler und Fairness - Der Scheduler sollte Fairness gewährleisten und Deadlocks vermeiden. - Er sollte auch einen hohen Durchsatz und minimale Antwortzeiten sicherstellen. ### Kapitel 2.3: Heap und Stack #### Speicherbereiche in Java - **Stack**: - Lokale Variablen und Methodenaufrufe werden hier gespeichert. - LIFO (Last-In-First-Out) Prinzip für das Hinzufügen/Entfernen von Frames. - Kein Garbage Collection erforderlich, Speicher wird automatisch verwaltet. - **Heap**: - Objekte und Instanzvariablen werden im Heap gespeichert. - Zugriff und Speichermanagement langsamer als beim Stack. - Garbage Collection wird verwendet, um nicht mehr benötigte Objekte zu entfernen. #### Funktionsweise des Stacks - **Stack Frames**: - Jeder Methodenaufruf erstellt einen neuen Frame auf dem Stack. - Enthält lokale Variablen, Operandenstack und Frame-Daten. - Wird beim Methodenaustritt entfernt. #### Funktionsweise des Heaps - Gemeinsamer Speicherbereich für alle Threads eines Prozesses. - Beinhaltet alle dynamisch allozierten Objekte. #### Typen von Variablen und deren Speicherorte - **Lokale Variablen**: Gespeichert im Stack des ausführenden Threads. - **Instanzvariablen**: Gespeichert im Heap, zugänglich für alle Methoden der Klasse. - **Klassenvariablen**: Ebenfalls im Heap gespeichert, jedoch im speziellen Bereich der Method Area. #### Vergleich: Stack vs. Heap - **Stack**: - Schnelle Allokation. - Automatische Speicherverwaltung. - Begrenzt durch die Größe jedes Threads. - **Heap**: - Langsamere Allokation. - Erfordert explizite Speicherfreigabe oder Garbage Collection. - Größe nur durch den verfügbaren Systemspeicher begrenzt. ![image](https://hackmd.io/_uploads/Hys3OvrMR.png) ### Kapitel 2.4: Thread-Sicherheit #### Grundlagen der Thread-Sicherheit - **Thread-Sicherheit**: Ein Programmteil ist thread-sicher, wenn es korrekt funktioniert, auch wenn es nebenläufig von mehreren Threads ausgeführt wird. - **Race Conditions**: Fehlerhafte Zustände, die entstehen, wenn die Reihenfolge der Ausführung der Operationen den Programmausgang beeinflusst. #### Probleme bei Nebenläufigkeit - **Read-Modify-Write**: Mehrere Threads lesen und ändern Werte, was zu inkonsistenten Zuständen führen kann. ![image](https://hackmd.io/_uploads/SyR6YDSG0.png) - **Check-Then-Act**: Mehrere Threads prüfen Bedingungen und handeln basierend darauf, was zu unerwünschten Effekten führen kann, wenn der Zustand sich zwischen Überprüfung und Aktion ändert. ![image](https://hackmd.io/_uploads/rkVxcvrMC.png) #### Umgang mit Race Conditions - **Locks und Synchronisation**: Verwenden von `synchronized` Blöcken oder Objekten zur Steuerung des Zugriffs auf Ressourcen. - **Atomare Operationen**: Einsatz von atomaren Variablen, die Operationen in einem Schritt ohne Unterbrechung durchführen, um Sicherheit zu gewährleisten. #### Kritische Bereiche - **Definition**: Ein Abschnitt des Codes, der nicht von mehr als einem Thread gleichzeitig ausgeführt werden darf. - **Schutzmechanismen**: - **Semaphoren**: Ermöglichen kontrollierten Zugriff durch eine begrenzte Anzahl von Threads. - **Monitore**: Verwenden von `synchronized` zur Definition von kritischen Bereichen innerhalb von Java-Objekten. #### Deadlocks und Livelocks - **Deadlock**: Zustand, in dem zwei oder mehr Threads auf Ressourcen warten, die von den anderen Threads gehalten werden. - **Livelock**: Threads ändern ständig ihren Zustand in Reaktion auf andere Threads, ohne Fortschritt zu machen. #### Strategien zur Vermeidung von Deadlocks - **Lock Ordering**: Einhalten einer festen Reihenfolge beim Erwerb von Locks. - **Timeouts**: Anwendung von Zeitlimits für Lock-Anfragen, um Deadlocks zu vermeiden. #### Best Practices - Minimiere den Zugriffsbereich von synchronisierten Blöcken, um Leistungseinbußen zu reduzieren. - Vermeide unnötige Synchronisation, um die Parallelität nicht einzuschränken. ### Kapitel 2.5: Semaphore #### Definition und Grundlagen - **Semaphore**: Eine Synchronisationshilfe, die den Zugang zu einer begrenzten Anzahl von Ressourcen kontrolliert. - Bestimmt durch einen Zähler, der angibt, wie viele Threads gleichzeitig auf den geschützten Bereich zugreifen dürfen. #### Arbeitsweise von Semaphoren - **acquire()**: Ein Thread versucht, den Semaphor zu betreten. Wenn der Zähler größer als 0 ist, wird er dekrementiert und der Zugang gewährt. Ist der Zähler 0, muss der Thread warten. - **release()**: Ein Thread verlässt den Semaphor, inkrementiert den Zähler und ermöglicht es anderen wartenden Threads, einzutreten. #### Java Implementierung - Java stellt die Klasse `java.util.concurrent.Semaphore` zur Verfügung, die robuste Methoden für die Semaphore-Verwaltung bietet. - Konstruktoren erlauben die Definition von Fairness-Regeln, die bestimmen, ob Threads in der Reihenfolge ihres Eintreffens Zugriff erhalten. #### Probleme und Lösungen - Semaphoren sind einfache, aber mächtige Werkzeuge für die Zugriffskontrolle auf Ressourcen. - **Fairness**: Optional kann ein fairer Zugriff eingestellt werden, um zu verhindern, dass Threads unverhältnismäßig lange warten. #### Anwendungsbeispiele - **Mutex (Mutual Exclusion Semaphore)**: Ein binärer Semaphor, der nur einen Thread zur Zeit in den kritischen Bereich lässt. - **Counting Semaphore**: Erlaubt mehreren Threads gleichzeitig den Zugang, limitiert durch den anfänglich gesetzten Zähler. #### Best Practices - Verwende Semaphoren zur Regelung des Zugriffs auf Ressourcen, die in begrenzter Anzahl verfügbar sind. - Achte auf die richtige Verwendung von `acquire()` und `release()`, um Deadlocks und andere Synchronisationsprobleme zu vermeiden. ![image](https://hackmd.io/_uploads/rkFE5DrfC.png) #### Zusammenfassung - Semaphore sind ein fundamentales Werkzeug in der nebenläufigen Programmierung, das hilft, die Integrität beim Zugriff auf gemeinsame Ressourcen zu sichern. - Korrekt eingesetzt, bieten sie eine leistungsstarke Lösung für viele Probleme der Nebenläufigkeit. ### Kapitel 2.6: Monitore #### Grundlagen von Monitoren - **Monitore**: Ein Synchronisationskonstrukt, das den Zugang zu einer Ressource auf einen Thread zur Zeit beschränkt, um Datenkonsistenz zu gewährleisten. - In Java wird die Synchronisation mittels des `synchronized` Schlüsselworts implementiert. #### Funktionsweise von Monitoren - **Synchronized Methoden und Blöcke**: - Ein `synchronized`-Block synchronisiert auf einem bestimmten Objekt, wodurch nur ein Thread zur Zeit den Block betreten kann. - `synchronized` Methoden sichern den Zugang zu einer Methode der Klasse ab. #### Kritische Bereiche - **Kritischer Bereich**: Ein Codeabschnitt, der nicht von mehreren Threads gleichzeitig ausgeführt werden darf. - Monitore sorgen dafür, dass kritische Bereiche durch das Locking-Mechanismus geschützt werden. #### Verwendung von Monitoren - **Synchronisation innerhalb von Klassenmethoden**: Synchronisiert auf dem `class`-Objekt der Klasse, wenn die Methode als `static synchronized` deklariert ist. - **Objekt-Monitore**: Jedes Objekt in Java besitzt intrinsisch einen Monitor, der durch `synchronized`-Methoden oder -Blöcke genutzt wird. #### Probleme und Lösungen - **Deadlock-Vermeidung**: Durch die Einführung einer konsistenten Lock-Reihenfolge und durch das Vermeiden von verschachtelten Locks kann das Risiko von Deadlocks reduziert werden. ![image](https://hackmd.io/_uploads/H1l5AqwHMA.png) - **Performance-Einbußen**: Übermäßiger Gebrauch von Synchronisation kann die Leistung beeinträchtigen, da Threads häufig blockiert werden. #### Best Practices - **Minimale Synchronisation**: Beschränke die Verwendung von `synchronized` auf das Nötigste, um die Ausführungsgeschwindigkeit zu maximieren. - **Feingranulare Locks**: Verwende mehrere kleinere Locks anstatt eines großen globalen Locks, um die Nebenläufigkeit zu verbessern. #### Zusammenfassung - Monitore sind ein wesentliches Werkzeug in der nebenläufigen Programmierung zur Sicherstellung der Datenintegrität. - Sie sollten sorgfältig und sparsam eingesetzt werden, um die Vorteile der Nebenläufigkeit nicht zu untergraben. ### Kapitel 2.7: Das Erzeuger/Verbraucher-Problem #### Grundkonzept - **Erzeuger/Verbraucher-Problem**: Ein klassisches Synchronisationsproblem, bei dem Erzeuger Daten produzieren und Verbraucher diese Daten konsumieren. - Ziel ist es, einen effizienten Datenfluss zwischen Erzeuger und Verbraucher zu gewährleisten, ohne Datenverlust oder Überlastung des Systems. #### Implementierung mit Monitoren - **Monitore**: Verwenden `synchronized` Schlüsselwort in Java, um den Zugriff auf gemeinsame Ressourcen zu regulieren. - **Warteräume**: `wait()` und `notify()` bzw. `notifyAll()` Methoden werden verwendet, um Threads in Warteräume zu senden und sie bei Verfügbarkeit der Ressourcen zu wecken. #### Szenario: Warteschlange - **Warteschlange**: Eine gemeinsam genutzte Datenstruktur zwischen Erzeugern und Verbrauchern. - Erzeuger fügen Elemente zur Warteschlange hinzu und Verbraucher entfernen sie. - Synchronisation notwendig, um Kollisionen und inkonsistenten Zustand der Warteschlange zu vermeiden. #### Probleme und Lösungen - **Vollständige und teilweise Synchronisation**: Vollständige Synchronisation verhindert, dass mehr als ein Thread gleichzeitig auf die Warteschlange zugreift, was die Leistung beeinträchtigen kann. - **Deadlocks vermeiden**: Durch korrektes Management von `wait()` und `notify()` Zuständen und durch Einhalten einer klaren Reihenfolge bei der Lock-Verwaltung. #### Best Practices - **Effiziente Nutzung von Ressourcen**: Stellen Sie sicher, dass die Warteschlange weder überfüllt noch leer ist, indem Sie passende Bedingungen für das Warten und Benachrichtigen setzen. - **Verwendung von Bedingungsvariablen**: Optimale Nutzung von `wait()` und `notifyAll()` zur Minimierung von Wartezeiten und Maximierung des Durchsatzes. ![image](https://hackmd.io/_uploads/r16W2DHzA.png) #### Erweiterte Synchronisationsmechanismen - **Bedingungsvariablen** erleichtern die Synchronisation, indem sie spezifischere Kontrolle über den Zustand von wartenden Threads bieten. - **Komplexe Szenarien**: Für komplexere Interaktionen zwischen Erzeugern und Verbrauchern können zusätzliche Synchronisationsmechanismen wie Semaphore oder erweiterte Monitore erforderlich sein. #### Zusammenfassung - Das Erzeuger/Verbraucher-Problem ist ein zentrales Thema in der nebenläufigen Programmierung, das effektive Lösungen zur Synchronisation und zum Ressourcenmanagement erfordert. - Durch den korrekten Einsatz von Synchronisationsmechanismen kann ein reibungsloser und effizienter Datenaustausch zwischen Erzeugern und Verbrauchern gewährleistet werden. ## Tutorium 1 ### Lösungen zu Übung 1: Threads Grundlagen #### 1.1 Prozesse und Threads 1. **Was ist der Unterschied zwischen Threads und Prozessen?** - Prozesse sind Instanzen eines laufenden Programms, die eigenen Adressraum und eigene Systemressourcen besitzen. Threads sind leichtgewichtige Prozesse, die innerhalb eines Prozesses laufen und dessen Ressourcen teilen. 2. **Was ist die Prozessumgebung?** - Die Prozessumgebung umfasst die Ablaufumgebung eines Prozesses, inklusive des Prozesskontextes und der zugeordneten Ressourcen wie CPU, Speicher, offene Dateien und Netzverbindungen. 3. **Welchen Inhalt hat ein Thread Control Block (TCB)?** - Ein Thread Control Block enthält wichtige Informationen über den Thread, wie den Thread-Zustand, Program Counter, CPU-Register, Stack Pointer und Thread-spezifische Daten. #### 1.2 Thread-Speicher 1. **Was ist der Unterschied zwischen dem Stack und dem Heap?** - Der Stack ist ein Speicherbereich für temporäre Variablen, die während der Ausführung von Methoden erstellt werden. Er arbeitet nach dem LIFO-Prinzip. Der Heap ist ein Speicherbereich für Objekte und Instanzvariablen, die während der Laufzeit dynamisch angelegt werden. 2. **Was sind lokale Variablen? Was sind Instanzvariablen? Was sind Klassenvariablen? Worin unterscheiden diese sich?** - Lokale Variablen: Innerhalb von Methoden definiert, Lebensdauer beschränkt auf die Methode. - Instanzvariablen: Innerhalb einer Klasse außerhalb einer Methode definiert; jede Instanz der Klasse hat ihre eigenen Kopien. - Klassenvariablen: Mit dem Schlüsselwort `static` definiert; es gibt nur eine Kopie dieser Variablen, die von allen Instanzen der Klasse geteilt wird. 3. **Was sind primitive Variablen? Was sind Referenzvariablen? Warum sprechen wir von einer Referenz?** - Primitive Variablen: Direkte Speicherung von einfachen Werten wie `int`, `char`, `boolean`. - Referenzvariablen: Speichern Adressen von Objekten auf dem Heap. - Wir sprechen von einer Referenz, weil Referenzvariablen auf den Speicherort eines Objekts verweisen, statt den Wert direkt zu halten. 4. **Wo wird die Referenz, wo das referenzierte Datum gespeichert?** - Die Referenz wird im Stack gespeichert, während das referenzierte Objekt im Heap abgelegt ist. #### 1.3 Thread-Zustände - Ergänzen Sie im untenstehenden Diagramm die Zustände von Java-Threads sowie die Methoden und Ereignisse, die zu den jeweiligen Zustandsübergängen führen. - **NEW**: Thread ist erstellt, aber noch nicht gestartet. - **RUNNABLE**: Thread kann ausgeführt werden, sobald ihm CPU-Zeit zugewiesen wird. - **BLOCKED**: Thread wartet auf den Zugriff auf eine synchronisierte Ressource. - **WAITING**: Thread wartet unbegrenzt, bis er speziell benachrichtigt wird. - **TIMED_WAITING**: Thread wartet für eine spezifische Zeit. - **TERMINATED**: Thread-Ausführung ist abgeschlossen. #### 1.4 Die Klasse Thread 1. **Zwei for-Schleifen A und B**: In der Praxis mit `System.out.println` für die Ausgabe. 2. **Parallelisierung**: Implementierung durch Vererbung von `Thread` und Ausführung in `run()`. 3. **Direkter Aufruf von `run()`**: Nein, dies würde die Methoden nicht in neuen Threads ausführen, sondern sie im aktuellen Thread sequenziell abarbeiten. #### 1.5 Das Interface Runnable 1. **Klasse Logger**: Implementierung mit einer `log()` Methode. 2. **Anwendung von Logger**: Anpassung der Klasse zum Einsatz von `Logger`. Probleme bei Vererbung von `Thread` aufgrund von Einschränkungen in der Java-Einervererbung. 3. **Lösung mit `Runnable`**: Umstellung auf `Runnable` ermöglicht die Nutzung von `Logger` Funktionen, während Thread-Funktionalität erhalten bleibt. ## Chapter 05 - Scala Grundlagen ### Kapitel 5.1: Scala - Grundlagen #### Was ist Scala? - **Entwicklung**: Entwickelt von Martin Odersky an der École Polytechnique Fédérale de Lausanne. - **Eigenschaften**: - 100% objektorientiert, ohne primitive Datentypen. - Kombiniert objektorientierte mit funktionaler Programmierung. - Statisch typisiert mit ausgezeichneter Typableitung. - **Laufzeit**: - Kann interpretiert und kompiliert werden. - Übersetzer generiert Java Bytecode, ausführbar auf jeder JVM. #### REPL - Read Evaluate Print Loop - **Funktion**: - Interaktive Umgebung für das Testen und Ausführen von Scala Code-Snippets. - Vergleichbar mit Jupyter Notebooks. - Bietet Multiline Paste Mode und Unterstützung für externe Bibliotheken. #### Konstanten und Variable Referenzen - **`val`**: - Definiert eine unveränderliche (immutable) Referenz. - Der Wert kann nach der Initialisierung nicht geändert werden. - Ähnlich wie `final` in Java. - **`var`**: - Definiert eine veränderliche (mutable) Referenz. - Erlaubt Änderungen des Werts nach der Initialisierung. #### Typsystem und Typableitung - **Statische Typisierung**: - Scala führt eine Typüberprüfung während der Kompilierung durch. - Typen können oft aus dem Kontext abgeleitet werden (Type Inference). - **Scala-Typenhierarchie**: - Keine primitiven Typen; alle Datentypen sind Objekte. - `AnyVal` und `AnyRef` als Basis für Wert- und Referenztypen. #### Grundlegende Datentypen und Operationen - **Wertdatentypen (`AnyVal`)**: - Beinhaltet Typen wie `Int`, `Double`, `Boolean`. - **Referenzdatentypen (`AnyRef`)**: - Scala's Pendant zu Java's `Object`. - **Operationen**: - `==` vergleicht Werte, nicht Referenzen. - Methoden wie `asInstanceOf`, `getClass`, und `toString` sind verfügbar. #### Schlüsselkonzepte - **Immutability**: - Bevorzugung von `val` über `var` zur Förderung unveränderlicher Datenstrukturen. - **Funktionale Programmierung**: - Funktionen sind Bürger erster Klasse, unterstützt durch Scala's mächtiges Typsystem und funktionale Features. ### Kapitel 5.2: Konstante und variable Referenzen mit `val` und `var` ![image](https://hackmd.io/_uploads/BJ5gIOBGA.png) #### Konstante Referenzen (`val`) - **Immutable**: Einmal zugewiesen, kann der Wert einer `val`-Variable nicht geändert werden. - **Initialisierung**: Muss bei der Deklaration initialisiert werden. - **Syntax**: `val name: Type = expression` - **Eigenschaften**: - Ähnlich wie `final` in Java. - Der zugewiesene Wert oder Objekt kann intern modifiziert werden, sofern es nicht selbst immutable ist. #### Variable Referenzen (`var`) - **Mutable**: Der Wert einer `var`-Variable kann nach der Initialisierung geändert werden. - **Initialisierung**: Ebenfalls bei der Deklaration erforderlich. - **Syntax**: `var name: Type = expression` - **Typableitung**: Der Datentyp kann weggelassen werden, wenn er aus dem Kontext ableitbar ist. #### Typableitung - **Type Inference**: Scala kann den Datentyp basierend auf dem zugewiesenen Ausdruck ableiten. - **Beispiel**: - `val x = 42` impliziert `val x: Int = 42` - `var y = "Hello"` impliziert `var y: String = "Hello"` #### Vor- und Nachteile - **Verwendung von `val`**: - Fördert die Unveränderlichkeit und damit die funktionale Programmierpraxis. - Reduziert Seiteneffekte und verbessert die Vorhersagbarkeit des Codes. - **Verwendung von `var`**: - Bietet Flexibilität, wo Veränderlichkeit erforderlich ist. - Kann zu Code führen, der schwieriger zu verstehen und zu warten ist. #### Praktische Tipps - **Bevorzugung von `val`**: Wo immer möglich, sollte `val` verwendet werden, um die Code-Sicherheit und Klarheit zu erhöhen. - **Einsatz von `var`**: In Szenarien, wo Werte dynamisch verändert werden müssen, z.B. in Schleifen oder Zustandsmaschinen. ### Kapitel 5.3: Wertdatentypen in Scala #### Scala-Typsystem - **Eigenschaften**: - Statisch: Typüberprüfung findet während der Kompilierzeit statt. - Implizit: Typen können oft aus dem Kontext hergeleitet werden (Type Inference). - Streng: Zugriff auf Daten und Objekte muss typkonform sein. - Keine primitiven Datentypen wie in Java; alle Datentypen sind Objekte. #### Hierarchie der Datentypen - **AnyVal**: Wertdatentypen, die direkt auf der JVM als primitive Typen abgebildet werden. - **AnyRef**: Referenzdatentypen, entsprechen `java.lang.Object`. - **Untertypen**: - `Nothing`: Untertyp von allen anderen Typen, keine Instanzen. - `Null`: Untertyp aller Klassen unterhalb von AnyRef, einzige Instanz ist `null`. - `Unit`: Typ für Methoden ohne Rückgabewert, entspricht `void` in Java. #### Methoden in Any - Alle Werte in Scala erben Methoden von `Any`, darunter: - `asInstanceOf[T]`: Konvertiert den Typ. - `getClass`: Liefert die Klasse des Objekts. - `isInstanceOf[T]`: Prüft, ob das Objekt vom Typ T ist. - `hashCode`: Liefert den Hashcode. - `toString`: Konvertiert das Objekt zu einem String. #### Numerische Datentypen - **Grundlegende Typen**: `Byte`, `Short`, `Int`, `Long`, `Float`, `Double`. - **Konvertierungen**: - Automatische Konvertierung von kleineren zu größeren Typen. - Manuelle Konvertierung mit Methoden wie `toLong`, `toFloat` usw. #### Zeichenketten - **Merkmale**: - Basieren auf Java Strings, aber mit zusätzlichen Features wie Multiline-Literalen und String-Interpolation. - Operationen: `+` für Verkettung, `*` für Wiederholung, Vergleich mit `==`. - **String Interpolation**: - Ermöglicht das Einsetzen von Variablen direkt in Strings. - Verwendet die Präfixe `s` und `f`, z.B. `s"Hello, $name"`. #### Tuples - **Eigenschaften**: - Geordnete Container, die zwei oder mehr Werte unterschiedlicher Typen enthalten können. - Zugriff über Indizes wie `_1`, `_2`, usw. - Nützlich für Funktionen, die mehrere Werte zurückgeben. #### Ausdrücke und Anweisungen - **Ausdrücke**: - Liefern Werte und haben einen wohldefinierten Typ. - **Anweisungen**: - Führen Aktionen aus, typischerweise ohne Rückgabewert (`Unit`). #### Conditional Structures - **If-Else**: - Verhält sich in Scala wie ein Ausdruck und liefert einen Wert. - **Match-Ausdrücke**: - Scala's flexible Form der Fallunterscheidung, ähnlich `switch` in anderen Sprachen. ### Kapitel 5.4: Ausdrücke, Anweisungen und Conditionals #### Grundlegende Konzepte ##### Ausdrücke vs. Anweisungen - **Ausdrücke (Expressions)**: - Jedes Stück Code, das einen Wert zurückliefert und einen wohldefinierten Typ hat. - Beispiele: `1 + 2`, `"Hello, " + name`, `if (x > 0) x else -x`. - **Anweisungen (Statements)**: - Stücke von Code, die hauptsächlich etwas tun (wie Daten ändern oder eine Aktion ausführen) und keinen Wert zurückliefern. - Typischerweise `Unit` in Scala, vergleichbar mit `void` in anderen Sprachen. ##### Blöcke - **Blöcke**: - Mehrere Ausdrücke, umgeben von geschweiften Klammern `{ ... }`. - Der Wert des Blocks ist der Wert des letzten Ausdrucks im Block. - Lokale Variablen innerhalb des Blocks sind nur im Block sichtbar. #### Conditional Structures ##### If-Else Conditionals - Scala behandelt `if-else` als Ausdruck, nicht als Anweisung. - Beispiel: ```scala val result = if (condition) value1 else value2 ``` - `result` erhält den Wert von `value1` oder `value2`, abhängig von `condition`. ##### Match-Ausdrücke - Ähnlich wie `switch`-Anweisungen in anderen Sprachen, aber mächtiger. - Beispiel: ```scala val result = x match { case 1 => "one" case 2 => "two" case _ => "other" } ``` - Werte können auf Muster abgeglichen werden, und der Ausdruck liefert den entsprechenden Wert. #### Schleifen und Iterationen ##### While und Do-While - Scala unterstützt traditionelle Schleifen durch `while` und `do-while`. - Beispiel: ```scala while (condition) { // Code to repeat } ``` ##### For-Comprehensions - Erweiterte `for`-Schleifen in Scala, die das Arbeiten mit Sammlungen vereinfachen. - Unterstützt sowohl einfache Iteration als auch komplexe Filter- und Transformationsoperationen. - Beispiel: ```scala for (i <- 1 to 10 if i % 2 == 0) yield i //Erzeugt eine Liste aller geraden Zahlen von 1 bis 10. ``` #### Ranges - Spezielle Art von Sammlungen, die eine Sequenz von gleichmäßig verteilten Integern repräsentieren. - Oft genutzt in Verbindung mit `for`-Schleifen. - Beispiel: ```scala val range = 1 to 5 //Erzeugt eine Reihe von Zahlen von 1 bis 5. ``` # AtomicInteger ### What does atomic mean? atomic= unteilbar. Only one thread can access it at a time ### What is an atomic Integer? AtomicInteger is used in multithreaded environments when you need to make sure that only one thread can update an int variable. The advantage is that no external synchronization is requried since the operations which modify it's value are executed in a thread-safe way #### Why it matters ```java= private int count; public int updateCounter(){ return ++count; } //multiple threads could call on .updateCounter() simulataneously, the result would not be correct ``` ### Instead, the code above should be replaced by ```java private AtomicLong count= new AtomicLong(0); public int updateCounter(){ return count.incrementAndGet(); } //the incrementAndGet method is guranteed to atomically increment the stored value and return its value without using any external synchronization ``` ### All Methods and Fields explained #### AtomicInteger /AtomicLong ```java public AtomicInteger number= new AtomicInteger(0); ``` Declare an instance of an AtomicInteger Variable. #### Konstruktor ```java public AtomicIncrementer(int startValue){...} this.number=new AtomicLong(startvalue); ``` the Constructor initializes the object to the specified starting value --- #### incrementAndGet: Herzstück von increment() ```java public void incrementAndGet(){ return number.incrementAndGet(); } ``` This method increments the counter by one and returns the new value. --- #### increment by One ```java public void increment(){...} ``` this method increments the current value of number by one. It does notneed to return the updated value. #### increment by specific value ```java public void incrementBy(int amount){...} number.addAndGet(amount); ``` --- #### incrementAndGet() ```java public void incrementBy(int amount){ number.addAndGet(amount); } ``` Number is incremented by one and return the new value. --- #### get from number ```java public int getValue(){...} return number.get(); ``` this method retrives the current value of the number. --- #### reset value of number ```java public void resetValue(){...} number.getAndSet(0); ``` This method resets the value of number to zero. --- #### set value of number ```java public int setValue(int newValue){...} return number.getAndSet(new Value); ``` Number sets the value to newVaue and return the old value. --- #### Difference between IncrementAndGet() and GetAndIncrement() IncrementAndGet() increments the value by one, then return the updated value usage: if you are counting new entries being added to a system and you need to use the new value in the system immediately getAndIncrement() returns the value first, then increments by one. usage: giving out IDs

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully