Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
1
Praktische Informatik 1
Prof. Dr. H. Schlingloff
2
Synchronisationsproblem
class TicTac implements Runnable{ static int summe = 0; Thread faden; private int wer; public TicTac(int w) { faden = new Thread(this); wer=w;} public void run() { if(wer==1) summe++; else summe--; } } public static void main(String[] args) { TicTac tic = new TicTac(1); TicTac tac = new TicTac(2); tic.faden.start(); tac.faden.start(); ... } package Parallelität; class TicTac implements Runnable{ static int summe = 0; Thread faden; private int wer; public TicTac(int w) { faden = new Thread(this); wer=w; } public void run() { System.out.println("Prozess "+ wer + " gestartet"); for(int i=1;i< ;i++) { if(wer==1) summe++; else summe--; System.out.println("Prozess "+ wer + " beendet"); public static void main(String[] args) { TicTac tic = new TicTac(1); TicTac tac = new TicTac(2); tic.faden.start(); tac.faden.start(); System.out.println("alles gestartet!"); try {tic.faden.join(); tac.faden.join();} catch (Exception e) {} System.out.println("Summe=" + summe);
3
Interleaving
4
Monitor class Monitor { private int i = 0;
synchronized void inc() { i++;} synchronized void dec() { i--;} int val() { return i; } } class TicTac implements Runnable{ static Monitor summe = new Monitor(); ... public void run() { if(wer==1) summe.inc(); else summe.dec(); } } package Parallelität; class Monitor { private int i = 0; synchronized void inc() { i++;} synchronized void dec() { i--;} int val() { return i; } } class TicTac implements Runnable{ static Monitor summe = new Monitor(); Thread faden; private int wer; public TicTac(int w) { faden = new Thread(this); wer=w;} public void run() { System.out.println("Prozess "+ wer + " gestartet"); for(int i=1;i< ;i++) { if (i% ==0) { System.out.println("T"+((wer==1)?"i":"a")+"c's i = " + i/ ); if(wer==1) summe.inc(); else summe.dec(); System.out.println("Prozess "+ wer + " beendet"); public static void main(String[] args) { TicTac tic = new TicTac(1); TicTac tac = new TicTac(2); tic.faden.start(); tac.faden.start(); try {tic.faden.join(); tac.faden.join();} catch (Exception e) {} System.out.println("Summe=" + summe.val());
5
synchronisierte Methoden
für jedes Objekt gibt es ein intrinsisches Schloss, welches den Zugang einschränkt während des Ablaufs einer synchronisierten Methode wird das Schloss verschlossen daher kann keine andere synchronisierte Methode dieses Objekts gleichzeitig ablaufen diese muss ggf. warten (Gefahr der Verklemmung (deadlock)!)
6
Synchronisationsanweisung
class Mutex {}; class TicTac implements Runnable{ static Mutex m = new Mutex(); ... public void run() { for(int i=1;i< ;i++) { synchronized(m) { if(wer==1) summe++; else summe--; } package Parallelität; class Monitor { private int i = 0; synchronized void inc() { i++;} synchronized void dec() { i--;} int val() { return i; } } class TicTac implements Runnable{ static Monitor summe = new Monitor(); Thread faden; private int wer; public TicTac(int w) { faden = new Thread(this); wer=w;} public void run() { System.out.println("Prozess "+ wer + " gestartet"); for(int i=1;i< ;i++) { if (i% ==0) { System.out.println("T"+((wer==1)?"i":"a")+"c's i = " + i/ ); if(wer==1) summe.inc(); else summe.dec(); System.out.println("Prozess "+ wer + " beendet"); public static void main(String[] args) { TicTac tic = new TicTac(1); TicTac tac = new TicTac(2); tic.faden.start(); tac.faden.start(); try {tic.faden.join(); tac.faden.join();} catch (Exception e) {} System.out.println("Summe=" + summe.val()); gleicher Effekt wie mit Monitor
7
E.W.Dijkstra: Dinierende Philosophen
5 Philosophen, eine Schüssel Spaghetti Zyklus: denken – essen – denken – ... Jeder benötigt zwei Gabeln zum Essen
8
ein einfacher Algorithmus
Jeder Philosoph macht folgendes: wiederhole: denke warte, bis linke Gabel frei, dann nimm sie warte, bis rechte Gabel frei, dann nimm sie iss gib beide Gabeln wieder frei verklemmungsbedroht! Implementierung siehe z.B.
9
etwas besserer Algorithmus
Jeder Philosoph macht folgendes: wiederhole: denke wiederhole solange bis beide Gabeln genommen wurden: warte, bis linke Gabel frei, dann nimm sie falls rechte Gabel nicht da, gib linke wieder frei warte, bis rechte Gabel frei, dann nimm sie falls linke Gabel nicht da, gib rechte wieder frei iss gib beide Gabeln wieder frei sinnlose Beschäftigung (livelock)!
10
noch besserer Algorithmus
Jeder Philosoph macht folgendes: wiederhole: denke warte, bis beide Gabeln frei, dann nimm sie iss gib beide Gabeln wieder frei (und teile dies den Nachbarn mit) Aufnehmen der Gabeln exklusiv (mutex) Aushungerungsmöglichkeit!
11
pragmatische Lösungsmöglichkeiten
Vor dem Aufnehmen der Gabel(n) eine zufällig bestimmte Zeitdauer warten (keine garantierte Fehlerfreiheit, wird aber in Kommunikationsprotokollen so gelöst) Unabhängiger Deadlock-Erkennungsalgorithmus („Wachhund“) Symmetriebruch oder feste Reihenfolgen Wartenummernverfahren
12
Kapitel 8: Java-Programmierung
8.1 Ereignisbehandlung, Benutzungsschnittstellen 8.2 Graphikprogrammierung 8.3 Applets, Internetprogrammierung
13
8.1 Ereignisbehandlung Benutzerinteraktion per Konsolschnittstelle
Programm wartet bis Benutzer „return“ eingibt Benutzerinteraktion per GUI (graphical user interface) Viele verschiedene Eingabemöglichkeiten, Ereignisse ablaufgesteuerte Programmierung: Programm = Folge von Anweisungen (= Methodenaufrufen) ereignisgesteuerte Programmierung: Programm = Sammlung von Behandlungsroutinen (= Methoden) für verschiedene Ereignisse
14
Ereignisse (events) Mausklick, Mausziehen, Mausbewegung, Return-Taste, Tastatureingabe, … Signale des Zeitgebers, Unterbrechungen, … programmerzeugte Ereignisse Für jedes Fenster wird ein Prozess gestartet, der auf die Ereignisse wartet und sie bearbeitet. Methoden zur Beobachtung von bestimmter Ereignisse; explizite Anmeldung der Beobachter
15
AWT und Swing zwei weit verbreitete Bibliotheken zur Realisierung von GUIs AWT (Abstract Window Toolkit): plattformunabhängige schwergewichtige Bibliothek (BS-Routinen) Swing: Bestandteil der Java-Runtime (leichtgewichtig); spezifisches Look-and-Feel, zusätzliche Komponenten, etwas moderner.
16
Fenster import java.awt.*; class Fenster extends Frame {
Fenster (String titel) { super(titel); setSize(160,120); setVisible(true); } } public class FensterDemo { public static void main(String[] args) { Fenster zumHof = new Fenster("zum Hof"); Fenster zurTür = new Fenster("zur Tür"); import java.awt.*; class Fenster extends Frame { Fenster (String titel) { super(titel); setSize(160,120); setVisible(true); } } public class FensterDemo { public static void main(String[] args) { Fenster zumHof = new Fenster("zum Hof"); Fenster zurTür = new Fenster("zur Tür");
17
Fensterbeobachter import java.awt.event.*;
class FensterBeobachter extends WindowAdapter{ public void windowClosing(WindowEvent e) { System.exit(0); } class Fenster extends Frame { Fenster (String titel) { ... FensterBeobachter fb = new FensterBeobachter(); addWindowListener(fb); package GUIAWT; import java.awt.*; import java.awt.event.*; class FensterBeobachter extends WindowAdapter{ public void windowClosing(WindowEvent e) { System.exit(0); } } class Fenster extends Frame { Fenster (String titel) { super(titel); FensterBeobachter fb = new FensterBeobachter(); addWindowListener(fb); setSize(240,180); setVisible(true); public class FensterDemo { public static void main(String[] args) { Fenster f = new Fenster("PI-1"); Analogie: Thread faden = new Thread(this); ... tic.faden.start();
18
Knöpfe und Knopfbeobachter
class KnopfBeobachter implements ActionListener{ public void actionPerformed(ActionEvent e) { System.out.println("Knopf gedrückt!"); } } class Fenster extends Frame { Fenster (String titel) { ... Button knopf = new Button("Knopf!"); knopf.addActionListener(new KnopfBeobachter()); add(knopf); package GUIAWT; import java.awt.*; import java.awt.event.*; class FensterBeobachter extends WindowAdapter{ public void windowClosing(WindowEvent e) { System.exit(0); } } class KnopfBeobachter implements ActionListener{ public void actionPerformed(ActionEvent e) { System.out.println("Knopf gedrückt!"); } class Fenster extends Frame { Fenster (String titel) { super(titel); addWindowListener(new FensterBeobachter()); setSize(240,180); setVisible(true); Button knopf = new Button("Knopf!"); knopf.addActionListener(new KnopfBeobachter()); add(knopf); public class FensterDemo { public static void main(String[] args) { Fenster f = new Fenster("PI-1");
19
aktive Komponenten Zur Verwendung aktiver Komponenten (Knöpfe, Schalter, …) sind immer folgende Schritte nötig Erzeugen – Button b = new Button () Registrieren – add(b) Verbinden zur Ereignisbehandlung – add....Listener(this) Methode zur Ereignisbehandlung schreiben actionPerformed, itemStateChanged, adjustmentValueChanged,...
20
anonyme Beobachter class Fenster extends Frame {
Fenster (String titel) { ... Button knopf2 = new Button("Knopf2"); knopf2.addActionListener (new ActionListener (){ public void actionPerformed(ActionEvent e) { System.out.println("Knopf2 gedrückt!"); }}); add(knopf2); package GUIAWT; import java.awt.*; import java.awt.event.*; class FensterBeobachter extends WindowAdapter{ public void windowClosing(WindowEvent e) { System.exit(0); } } class KnopfBeobachter implements ActionListener{ public void actionPerformed(ActionEvent e) { System.out.println("Knopf gedrückt!"); } class Fenster extends Frame { Fenster (String titel) { super(titel); addWindowListener(new FensterBeobachter()); setSize(240,180); setVisible(true); Button knopf = new Button("Knopf!"); knopf.addActionListener(new KnopfBeobachter()); add(knopf); setLayout(new FlowLayout()); Button knopf2 = new Button("Knopf2"); knopf2.addActionListener (new ActionListener (){ System.out.println("Knopf2 gedrückt!"); }}); add(knopf2); public class FensterDemo { public static void main(String[] args) { Fenster f = new Fenster("PI-1");
21
Layout-Fragen mehrere verschiedene Layouts verfügbar! BorderLayout
class Fenster extends Frame { Fenster (String titel) { ... setLayout(new FlowLayout()); Button knopf2 = ... mehrere verschiedene Layouts verfügbar! BorderLayout FlowLayout GridLayout CardLayout GridBagLayout Schachtelung von Layouts möglich package GUIAWT; import java.awt.*; import java.awt.event.*; class FensterBeobachter extends WindowAdapter{ public void windowClosing(WindowEvent e) { System.exit(0); } } class KnopfBeobachter implements ActionListener{ public void actionPerformed(ActionEvent e) { System.out.println("Knopf gedrückt!"); } class Fenster extends Frame { Fenster (String titel) { super(titel); addWindowListener(new FensterBeobachter()); setSize(240,180); setVisible(true); Button knopf = new Button("Knopf!"); knopf.addActionListener(new KnopfBeobachter()); add(knopf); setLayout(new FlowLayout()); Button knopf2 = new Button("Knopf2"); knopf2.addActionListener (new ActionListener (){ System.out.println("Knopf2 gedrückt!"); }}); add(knopf2); public class FensterDemo { public static void main(String[] args) { Fenster f = new Fenster("PI-1");
22
8.2 Graphikprogrammierung
Mausevents werden nach dem selben Schema behandelt Ausgabe graphischer Elemente (Linien, Kreise, Vielecke, Polygone…) mit Objekt der Klasse Graphics Methoden: drawLine, fillPolygon, drawOval, … Konstruktor getGraphics() addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { x1 = e.getX(); y1 = e.getY(); } ...
23
ein Malprogramm ... addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) { x1 = e.getX(); y1 = e.getY(); } public void mouseReleased(MouseEvent e) { x2 = e.getX(); y2 = e.getY(); Graphics g = getGraphics(); g.setColor(Color.blue); int w=Math.abs(x1-x2), h=Math.abs(y1-y2); switch (modus) { case 1: g.fillRect(x1,y1,w,h); break; case 2: g.fillOval(x1,y1,w,h); break; } } }); package Grafik; import java.awt.*; import java.awt.event.*; class GrafikFenster extends Frame{ private static int x1, y1, x2, y2; private static int modus = 0; GrafikFenster(String titel, int breite, int höhe){ super(titel); setLayout(new FlowLayout()); Button RechteckButton = new Button ("Rechteck"); RechteckButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { modus = 1; } }); add(RechteckButton); Button OvalButton = new Button ("Oval"); OvalButton.addActionListener(new ActionListener() { modus = 2; } }); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { x1 = e.getX(); y1 = e.getY(); } public void mouseReleased(MouseEvent e) { x2 = e.getX(); y2 = e.getY(); Graphics g = getGraphics(); g.setColor(Color.blue); int w=Math.abs(x1-x2), h=Math.abs(y1-y2); switch (modus) { case 1: g.fillRect(x1,y1,w,h); break; case 2: g.fillOval(x1,y1,w,h); break; default: break; }); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); } setBackground(Color.lightGray); setSize(breite, höhe); setVisible(true); public class GrafikDemo { public static void main(String[] args) { GrafikFenster f = new GrafikFenster("Künstler",800,600);
24
Animationen Bei Veränderung des Fensters (z.B. Vergrößern) geht die Zeichnung verloren paint (Graphics g) zur Ausgabe der Zeichnung, wird bei Fensterveränderungen automatisch aufgerufen paint muss so programmiert werden, dass es alle Zeichnungsobjekte ausgibt Eintrag von Zeichnungsobjekten in Collection (z.B. Set), iterative Ausgabe aller Elemente Die selbe Methode kann für Animationen benutzt werden Aufruf von paint() in eigenem Thread, alle 40 ms add(new Checkbox("check!"));
Ähnliche Präsentationen
© 2025 SlidePlayer.org Inc.
All rights reserved.