Kapitel 2, Teil 3 - Department of Information Systems

Werbung
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
14. Dateien
• Datei (engl. file): Folge von „Datensätzen“ (i. Allg.)
im dauerhaften (persistenten) Sekundärspeicher
• am Ende erweiterbar
• (meist) Datensätze zusammengefasst in gleichgroßen Seiten (z.B. 4 KB)
• beim Zugriff auf Sekundärspeicher wird eine vollständige Seite
übertragen → Pufferung
• logische Dateien auch zur Kommunikation zwischen Prozessen
(→ Pipes, VS)
129
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Formen von Dateien
• sequentielle Datei: Datensätze der Reihe nach bearbeitet
• Datei mit wahlfreien Zugriff (random access file):
• auf beliebigen Datensatz direkt zugreifbar (vgl. Array)
• hierauf aufbauend: B-Bäume, (dynamische) Hashverfahren, . . .
• nicht bei Magnetbändern, Pipes,. . . ,
aber bei Platten, CDs, DVDs. . .
130
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
14.1 Dateien in Java
• in Java: komplizierte Klassenhierarchie unterschiedlicher
Dateiformen
• auf Bytes bzw. Zeichen
• zum Lesen bzw. Schreiben
• gepuffert bzw. ungepuffert
• hier nur Ausschnitt (Klassen sind jeweils Unterklassen von Object)
131
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Klassenhierarchie für Dateien
• InputStream (abstrakt)
→ Byte-Datei lesen
• ByteArrayInputStream
• FileInputStream
• FilterInputStream (mit 4 Unterklassen)
• ObjectInputStream implements ObjectInput
• PipedInputStream
• SequenceInputStream
• RandomAccessFile implements DataInput, DataOutput
132
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Klassenhierarchie für Dateien (2)
• OutputStream (abstrakt)
→ Byte-Datei schreiben
• ByteArrayOutputStream
• FileOutputStream
• ObjectOutputStream
• FilterOutputStream (mit 3 Unterklassen)
• PipedOutputStream
• Reader (abstrakt, 6 Unterklassen)
• Writer (abstrakt, 7 Unterklassen)
→ Zeichen-Datei lesen
→ Zeichen-Datei schreiben
• ...
133
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
14.2 Sequentielle Dateien in Java
public class ObjectInputStream extends InputStream
implements ObjectInput, ObjectStreamConstants{
public ObjectImportStream(InputStream in) // Konstruktor
throws IOExeption, StreamCorruptedException;
public int available() throws IOException;
public void close() throws IOException;
public int read() throws IOException;
public int read(byte[] data, int offset, int length) ...
public boolean readBoolean() throws IOException;
public byte readByte() throws IOException;
public char readChar() throws IOException;
134
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Sequentielle Dateien in Java (2)
public double readDouble() throws IOException;
public float readFloat() throws IOException;
public int readInt() throws IOException;
public long readLong() throws IOException;
public short readShort() throws IOException;
public final Object readObject() throws IOException,
OptionalDataException, ClassNotFoundException;
protected final boolean enableResolveObject(boolean enable)
throws SecurityException;
protected Object resolveObject(Object o) throws IOException
...}
135
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Sequentielle Dateien in Java (3)
public class ObjectOutputStream extends OutputStream
implements ObjectOutput{
public ObjectOutputStream(OutputStream o) throws IOException;
public void flush() throws IOException;
public void write(int data) throws IOException;
public void write(byte[]b) throws IOException;
public void write(byte[]b, int off, int len)
throws IOException;
public void writeBoolean(boolean b) throws IOException;
public void writeByte(int data) throws IOException;
public void writeBytes(String data) throws IOException;
136
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Sequentielle Dateien in Java (4)
public void writeChar(int data) throws IOException;
public void writeChars(String data) throws IOException;
public void writeDouble(double data) throws IOException;
public void writeFloat(flout data) throws IOException;
public void writeInt(int data) throws IOException;
public void writeLong(long data) throws IOException;
public void writeShort(short data) throws IOException;
public void writeObject( Object obj) throws IOException;
...}
137
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Verwendung von ObjectOutputStream
import java.io.*;
public class Test1{
public static void main(String argv[]){
try{
FileOutputStream fos =
new FileOutputStream("test.data");
ObjectOutputStream out =
new ObjectOutputStream(fos);
for(int i=1; i<1000; i++){
out.writeInt(i);
out.writeDouble(1.0/(double) i);}
out.flush();
out.close();}
catch (Exception e){
e.printStackTrace();}}
}
138
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Verwendung von ObjectInputStream
import java. io.*;
public class Test2{
public static void main(String argv[]){
int i; double sum=0.0;
try{
FileInputStream fis =
new FileInputStream("test.data");
ObjectInputStream in =
new ObjectInputStream(fis);
while (true){
i = in.readInt();
sum += in.readDouble();}}
catch (EOFException a){
System.out.println("H("+i+"):"+ sum);}
catch (Exception e){e.printStackTrace();}}
}
bei Binär- und Text-Dateien (z.B. mit Editor erstellt) direkt von fis lesen
z.B. char c = (char) fis.read();
139
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
14.3 Serialisierung
• die Klassen ObjectInputStream und ObjectOutputStream
ermöglichen nicht nur das Lesen bzw. Schreiben von Basiswerten
sondern auch von Objekten
• ein Objekt enthält/referenziert oft andere Objekte
( → Objektgraph, ggfs. zyklisch)
→ I/O eines Objekts erfordert rekursiven I/O
des gesamten zugehörigen Objektgraphen
• zur Speicherung in einer Datei wird ein Objektgraph von Java
automatisch in eine Byte- bzw. Zeichenfolge transformiert
• beachte: das Einlesen eines serialisierten Objektgraphen kann
in einem „veränderten Umfeld“ (andere Rechner, andere Klassen)
erfolgen
→ bei Serialisierung: Meta-Informationen (über Klassen,. . . ) mitangelegt 140
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Serialisierung (2)
• die Serialisierung in Java ist äußerst komfortabel
(im Vergleich zu anderen Sprachen, wo nur I/O von Basiswerten
möglich!)
• Objekte sind nur serialisierbar, wenn die zugehörige Klasse das
Interface Serializable implementiert
• durch Überschreiben der Methoden readObject und
writeObject lässt sich der Serialisierungsmechanismus an
spezielle Benutzerbedürfnisse anpassen
141
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Serialisierung (3)
Klassendiagramm
möglicher Objektgraph
Department:
Department
name
1
*
Employee
Vector/List:
Element:
Marketing
Element:
null
name
addEmployee,...
Employee:
Kötter
Employee:
Kämper
bei Serialisierung:
• Objektreferenzen werden ersetzt durch Positionsangaben
der referenzierten Objekte in der erzeugten Byte- bzw. Zeichenfolge
• jedes Objekt wird nur einmal abgelegt (auch bei Zyklen und
Mehrfachreferenzen)
142
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Datei Department.java
package serialexample;
// im gleichnamigen Verzeichnis
import java.io.*;
import java.util.*;
public class Department implements Serializable{
protected String name;
protected Vector<Employee> employees = new Vector<Employee>();
public Department(String name){
this.name = name;}
public void addEmployee(Employee e){
employees.addElement(e);}
public Employee getEmployee(int index){
return employees.elementAt(index);}
public String getName(){return name;}
}
143
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Datei Employee.java
package serialexample;
import java.io.*;
public class
Employee implements Serializable{
protected String name;
protected Department dep;
public Employee(String n, Department d){
name = n; dep = d; dep.addEmployee(this);}
public String getName(){return name;}
}
144
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Datei Test.java
package serialexample;
import java.io.*;
public class Test{
public static void main(String argv[]) throws Exception{
Department dep = new Department("Marketing");
new Employee("Kämper", dep);
new Employee("Kötter", dep);
FileOutputStream fos = new FileOutputStream("test.dat");
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(dep);
out.flush();
out.close();
FileInputStream fis = new FileInputStream("test.dat");
ObjectInputStream in = new ObjectInputStream(fis);
Department dep2 = (Department) in.readObject();
in.close();
System.out.println(dep2.getName()+":" +
dep2.getEmployee(0).getName()+"," + dep2.getEmployee(1).getName();}
}
145
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
14.4 Dateien mit wahlfreiem Zugriff in Java
pubic class RandomAccessFile implements DataInput, DataOutput{
public RandomAccessFile(String filename, String mode)
throws IOException
// modes: "r" (lesen) oder "rw" (lesen und schreiben)
public RandomAccessFile(File file, String mode) ...
public native long getFilePointer() throws IOException;
public native void seek(long pos) throws IOException;
public int read() throws IOException;
public int read(byte[] buffer) throws IOException;
public int read(byte[] buffer, int off, int count) ...
public final boolean readBoolean() throws IOException;
analog: readByte,readChar,readDouble,readFloat,readInt,...
146
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Dateien mit wahlfreiem Zugriff in Java (2)
public void write(int b) throws IOException;
public void write(byte[] buffer) throws IOException;
public void write(byte[] buffer, int off, int count) ...
public final void writeBoolean(boolean b) ...
analog: writeByte, writeChar,...
public native long length() throws IOException;
public native void close() throws IOException;
}
147
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Wahlfreier Zugriff
import java.io.*;
class Test{
public static void main(String[] args){
try {
RandomAccessFile raf = new RandomAccessFile(args[0],"rw");
long start =
raf.getFilePointer();
for (int i=0; i<1000; i++)
raf.writeInt(i);
raf.seek((long) start + 100);
System.out.println(raf.readInt());
// → 25
raf.seek((long) start + 3000);
System.out.println(raf.readInt());
// → 750
raf.close();}
catch (IOException e){System.out.println(e);}}
}
Verwendung: javac Test.java; java Test test.dat
148
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
15. Wert- vs. Referenzsemantik
Wertsemantik
• bei einer Zuweisung bzw. Parameterübergabe wird der Wert kopiert
• beide Kopien werden unabhängig voneinander verwendet
• Vergleich w1 == w2 liefert true, gdw. w1 und w2 den gleichen Wert
haben (ggf. aber unterschiedliche Speicherplätze)
• in Java verwendet bei Basiswerten (int, float, . . . ), z.B.
int i = 1;
int k = 1;
int j = i;
j++;
System.out.println(i+j);
→ 3
System.out.println(i==k);
→ true
149
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Referenzsemantik
• bei einer Zuweisung bzw. Parameterübergabe wird die Referenz kopiert
(nicht der Wert)
• beide Referenzen verweisen anschließend auf den gleichen
Speicherbereich
• Änderungen beeinflussen das (eine!) durch beide Referenzen
bezeichnete Objekt
• in Java verwendet bei Arrays und Objekten
• Vergleich o1 == o2 liefert true,
gdw. o1 und o2 das identische Objekt referenzieren
• Wertsemantik-Vergleich von Objekten/Arrays möglich durch:
geeignetes Überschreiben der Methode equals (aus Klasse Object)
• default von equals: Referenzsemantik
150
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Wert- und Referenzsemantik
class Punkt{
protected int x, y;
public Punkt(int x0, int y0){x=x0; y=y0;}
public void verschiebe(int dx, int dy){x+=dx; y+=dy;}
public boolean equals(Punkt p){return x==p.x && y==p.y;}
public Punkt copy(){return new Punkt(x,y);}
}
...
Punkt p1 = new Punkt(1,2);
Punkt p2 = p1.copy();
Punkt p3 = p1;
System.out.println(p1 == p2);
→ false
System.out.println(p1.equals(p2));
→ true
p3.verschiebe(3,4);
System.out.println(p1.equals(p2));
→ false
151
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
16. Java-Speicherverwaltung
• der Speicherplatz für nicht mehr erreichbare Objekte wird vom
Laufzeitsystem automatisch freigegeben und anderweitig
wiederverwendet (garbage collection)
→ enorme Programmiererleichterung gegenüber anderen Sprachen
(z.B. C, Pascal)
→ (geringer) Laufzeitoverhead
Beispiel:
Punkt p = new Punkt(2,5);
p = new Punkt(1,3);
• das mit new Punkt(2,5) erzeugte Objekt ist nicht mehr erreichbar
• der zugehörige Speicherplatz wird bei Bedarf freigegeben
152
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Speicherverwaltung (Fortsetzung)
• durch Beseitigung aller Referenzen:
→ gezielte Freigabe eines Objekts,
z.B. p = null; (“leere Referenz”)
• vor der Freigabe wird, falls vorhanden,
die finalize-Methode des Objekts ausgeführt
• hierdurch können ggfs. weitere Ressourcen wie Dateien freigegeben
werden
Beispiel:
public void finalize(){
... vom Objekt verwendete Datei schließen ...}
153
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
17. Applets
• Applets sind spezielle Java-Klassen,
die von einem Webbrowser (clientseitig) ausgeführt werden
• sie werden über Applet-Tags in HTML-Seiten eingebunden
• eingeschränkte Rechte (keine Dateizugriffe, eingeschränkte
Kommunikation) → Sandbox
• statt einer main-Methode:
Methoden init, start, stop, destroy bei Bedarf
überschreiben
154
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Applets (2)
init(): initialisiert Applet (vgl. Konstruktor)
stop(): wird ausgeführt, wenn Browser Appletseite verlässt
ggf. Ressourcen freigeben, Animation anhalten,. . .
start(): ausgeführt, wenn Browser Appletseite erneut anzeigt
ggf. Ressourcen wieder bereitstellen, Animation
reaktivieren,. . .
destroy(): ausgeführt, wenn Applet zerstört wird
ggf. Ressourcen freigeben
155
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Applet “Zähler”
HTML-Seite mit Applet-Tag:
<html>
<head><title>Zaehler-Applet</title></head>
<body>
<H2><font color=cyan>Test-Applet</font></H2><br>
<applet code="Zaehler.class" width=300 height=120>
Ihr Browser unterstützt Java leider nicht!
</applet>
</body>
</html>
156
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Applet “Zähler” (2)
import java.applet.*;
import java.awt.*;
import java.lang.*;
import java.awt.event.*;
public class Zaehler extends Applet implements ActionListener{
protected TextField zstand = new TextField("0",4);
protected Button weiter
= new Button("Weiterzaehlen");
protected Button zurueck
= new Button("Zuruecksetzen");
public void init(){System.out.println("Applet initialisiert");
setBackground(Color.white);
add(new Label("Zaehlerstand: "));
add(zstand);
add(weiter);
add(zurueck);
weiter.addActionListener(this);
zurueck.addActionListener(this);}
157
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Applet “Zähler” (3)
public void start(){System.out.println("Applet gestartet");}
public void stop(){System.out.println("Applet gestoppt");}
public void destroy(){System.out.println("Applet entfernt");}
public void actionPerformed(ActionEvent event){
if (event.getSource() == weiter)
zstand.setText(""+(1+ Integer.parseInt(zstand.getText())));
else if (event.getSource() == zurueck)
zstand.setText("0");}
}
158
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Kritzel-Applet
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble1 extends Applet{
protected int x, y;
protected Graphics g;
private class MyMouseListener extends MouseMotionAdapter{
public void mouseMoved(MouseEvent e){
x = e.getX(); y = e.getY();}
public void mouseDragged(MouseEvent e){
int newx = e.getX(); int newy = e.getY();
g.drawLine(x,y,newx,newy);
x = newx; y = newy;}}
public void init(){
g = getGraphics();
getAudioClip(getCodeBase(),"gong.au").play();
addMouseMotionListener(new MyMouseListener());}
}
159
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
18. Nebenläufigkeit
• mehrere Anweisungsfolgen (Threads) lassen sich nebenläufig
ausführen
• (u.a.) damit logisch unabhängige Programmteile nicht unnötig
sequentialisiert werden und sich ggf. gegenseitig blockieren
• z.B. beim Überwachen von Sensoren oder
Kommunikationsverbindungen
• auf einem Prozessor: Threads verzahnt ausgeführt, z.B.
Thread1
Thread2
Thread3
Thread1
Thread3
Thread2
...
Zeit
160
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Thread in Java
• muss Interface Runnable implementieren
(insbesondere Methode run())
oder Klasse Thread erweitern (und run() überschreiben)
• Thread t wird gestartet durch t.start()
• dies bewirkt Aufruf der Methode run() des Thread-Objekts
• weitere Features: (→ Literatur)
setPriority(p), ThreadLocal, volatile, holdsLock,
join, TimerTask, ThreadGroup
161
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Kritzel-Applet mit Farbwechsel
public class Scribble extends Applet{
protected int x, y;
protected Graphics g;
protected Thread th;
private class MyMouseListener extends MouseMotionAdapter{
... wie vorher ...}
private class ColorChanger extends Thread{
public void run(){
try{while (true){
setBackground(Color.white);
sleep(10000);
// in msec
setBackground(Color.yellow); sleep(10000);}}
catch(InterruptedException e){System.out.println("beendet");}}}
public void init(){
g = getGraphics();
addMouseMotionListener(new MyMouseListener());
th = new ColorChanger();
th.start();}
public void stop(){th = null;}
}
162
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Kommunikation
• Threads können über gemeinsam benutzte Objekte/Variablen
kommunizieren
• Problem: durch Threadwechsel ggf. ungewollte Effekte
Beispielszenario: verzahnte Überweisungen (vgl. SimpelBank)
konto2.saldo
Thread
80
Thread1 : konto2.getSaldo() → 80
80
Thread2 : konto2.getSaldo() → 80
90
Thread2 : konto2.setSaldo(80+10)
90 (statt 100)
Thread1 : konto2.setSaldo(80+10)
163
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Synchronisation durch Java-Monitore
• ungewollte Threadverzahnung muss verhindert werden!
• hierzu: Methoden als synchronized kennzeichnen
• zu jedem Zeitpunkt kann nur ≤ ein Thread
synchronized-Methoden jedes Objekts ausführen
• ein weiterer Thread, der eine synchronized-Methode des Objekts
aufrufen will, wartet (→ Warteschlange), bis die
synchronized-Methoden von anderen Threads verlassen wurden
Beispiel:
public static synchronized void ueberweise(Konto ziel, int betrag){
saldo = saldo - betrag;
ziel.setSaldo(ziel.getSaldo()+betrag);}
164
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Synchronisation von Anweisungsfolgen
• auch Anweisungsfolgen lassen sich als synchronized
kennzeichnen
• z.B.: synchronized(this){
ziel.setSaldo(ziel.getSaldo()+betrag);}
• allgemein: synchronized(hSperrobjekti){hAnweisungi∗ }
165
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
wait() und notify()
Szenario:
• während der Ausführung einer synchronized-Methode m muss
gewartet werden, bis eine Bedingung (abh. von Attributen) erfüllt ist
• wenn m die Exklusivrechte nicht aufgibt: Stillstand!
Abhilfe:
• durch wait(); kann der Thread angehalten werden
• ein anderer Thread kann dann weiterarbeiten (und die Attribute ändern)
(auch durch eine synchronized-Methode)
• durch notify() kann ein angehaltener Thread reaktiviert werden
• alternativ: notifyAll() reaktiviert alle hierauf wartenden Threads
• wait() und notity() nur in synchronized-Methoden verwendbar
166
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Dinierende Philosophen
public class Dining{
private static final int n = 5; // #Philosophen
protected Staebchen stab[] = new Staebchen[n];
private class Staebchen{... s.u....}
private class Philosoph implements Runnable{
private int nr;
public Philosoph(int i){nr = i;}
public void essen(){stab[nr].nehmen(); stab[(nr+n-1)%n].nehmen();
System.out.println("Philosoph "+nr+" isst");}
// ggf. Deadlock!
public void denken(){stab[nr].ablegen(); stab[(nr+n-1)%n].ablegen();
System.out.println("Philosoph "+nr+" denkt");}
public void run(){while(true){essen(); denken();}}}
public Dining(){
for(int i=0; i<n; i++) stab[i] = new Staebchen();
for(int i=0; i<n; i++) new Thread(new Philosoph(i)).start();}
public static void main(String[] args){new Dining();}
}
167
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Dinierende Philosophen: Klasse Stäbchen
private class Staebchen{
private boolean verfuegbar = true;
public synchronized void nehmen(){
try{while (!verfuegbar) wait();
verfuegbar=false;}
catch(Exception e){System.out.println("Abbruch");}}
public synchronized void ablegen(){
verfuegbar = true;
notify();}
}
168
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
19. Generelle Programmierprinzipien
19.1 Lesbarkeit verbessern
• aussagekräftige Namen
schlecht: hilf, merker, speicher, feld, messreihe, x
besser: DurchschnittsUmsatz, ProfilTiefe
• Konstanten benennen (→ auch leichter änderbar)
static final int GrundPraemie = 150;
static final int Zulage = 20;
Praemie = Grundpraemie +
Zulage * DienstJahre;
statt
p = 150 + 20*d
169
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Lesbarkeit verbessern (2)
• bei kurzen Bezeichner (wie x) Verwechslungsgefahr durch Tippfehler
• wenig aussagekräftige Kommentare weglassen, z.B.
i = i+1; // i inkrementieren
• Zusammengehörigkeit durch das Layout hervorheben (→ Einrücktiefe)
170
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
19.2 Problemadäquate Datentypen
• möglichst direkte Umsetzung der Datenstrukturen der Anwendung
in Programmiersprache, hierzu:
• geeignete Basistypen, z.B. int stunde; statt float stunde;
• Aufzählungstypen (enum), Unterbereichstypen statt int
• Typen so wählen, dass unzulässige Werte zu Typfehlern führen
171
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Unterbereichstypen
• bieten Teilmengen der Werte eines anderen Typs
• Beispiel: 0..23 statt int
• in Java im Gegensatz zu anderen Sprachen (Pascal,Ada,. . . ):
keine syntaktische Unterstützung von Unterbereichstypen
• in Java simulierbar
172
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Simulation von Unterbereichstyp
public final class Stunde{
private int st;
public class StundeException extends Exception{}
public Stunde(int s) throws StundeException{
if ((s<0) || (s>23)) throw new StundeException();
st = s;}
public void next(){st = (st+1) % 24;}
public String toString(){return ""+st;}
}
• Anwendung: z.B.
Stunde st = new Stunde(23);
st.next(); System.out.println(st);
173
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
19.3 Schrittweise Verfeinerung
• zur Strukturierung grobe Version mit abstrakten Daten und abstrakten
Befehlen ausgehend von Spezifikation einer Systemkomponente
schrittweise verfeinern
• Schritte der groben Versionen bleiben als Kommentare in detaillierter
Version
• hierfür günstig: Hypertext-Editor (z.B. Visual Studio.NET)
• Einrücktiefe dokumentiert Verfeinerungsniveau
• Reihenfolge der Verfeinerung kann günstig gewählt werden
z.B. Kern vor Initialisierung, Schleifen und Verzweigungen früh
• kein Geheimnisprinzip
174
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
Beispiel: Schrittweise Verfeinerung
//*********************************************
// Sortieren eines Arrays durch direkte Auswahl
//*********************************************
public static void selSort(int[] a){
// bis Restarray einelementig
// Minimum in Restarray suchen
// Minimum mit erstem Element vertauschen
}
175
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
1. Verfeinerung
public static void selSort(int[] a){
// bis Restarray einelementig
for(int i = 0; i <= a.length-2; i++)
// Minimum in Restarray suchen
// Index des Minimums initialisieren
// fuer jedes Element des Restarrays
// Element bei Min-Bildung beachten
// Minimum mit erstem Element vertauschen
}
176
1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP
2. Verfeinerung
public static void selSort(int[] a){
// bis Restarray einelementig
for(int i = 0; i <= a.length-2; i++){
// Minimum in Restarray suchen
// Index des Minimums initialisieren
int minidx = i;
// fuer jedes Element des Restarrays
for (int j = i+1; j <= a.length-1; j++){
// Element bei Min-Bildung beachten
if (a[j] < a[minidx])
minidx = j;}
// Minimum mit erstem Element vertauschen
int hilf = a[i]; a[i] = a[minidx];
a[minidx] = hilf;}
}
177
Herunterladen