Thread

Werbung
EINFÜHRUNG IN DIE
PROGRAMMIERUNG
FORTGESCHRITTENE KONZEPTE
Tobias Witt!
!
26.03.2014
FEHLERBEHANDLUNG
KLASSISCHER ANSATZ
•
Fehlercode als Rückgabewert von Methoden!
‣
String ➜ Fehlercode als String!
‣
int ➜ Fehlercode als Integer!
‣
List ➜ ???!
‣
void ➜ ???
KLASSISCHER ANSATZ
PROBLEME
•
Fehlerbehandlung stets direkt!
•
Abfrage von Rückgabewert nötig!
‣
•
Verschiedene Fehler - verschiedene FehlerRückgabewerte!
Einschränkung des Werte-Bereichs der Methode
AUSNAHMEN - EXCEPTIONS
•
Fehler als „Ausnahme“ explizit oder implizit
ausgelöst!
•
Fehlerursache „wirft“ Exception!
•
Fehlerbehandler „fängt“ Exception
AUSNAHMEN - EXCEPTIONS
•
Geprüfte Ausnahmen (Checked Exceptions)!
‣
•
Ungeprüfte Ausnahmen (Unchecked Exceptions)!
‣
•
Müssen behandelt werden!
Müssen nicht unbedingt behandelt werden!
Jede nicht behandelte Exception bricht das Programm ab!
AUSNAHMEN BEISPIELE
NullPointerException
Methode wird auf null aufgerufen
ArrayIndexOutOfBoundsException
Zugriff auf nicht existierenden ArrayIndex
ClassCastException
Casting nicht möglich
NumberFormatException
z.B. bei
Integer.parseInt("bogus")
FileNotFoundException
Dateiname existiert nicht
Exception KLASSE
•
Geprüfte Exceptions:!
‣
•
Erben von Exception
Ungeprüfte Exceptions:
‣
Erben von RuntimeException
AUSNAHMEN BEHANDELN
Ungeprüfte NumberFormatException
public class Spiel {
public static void main(String[] args) {
int a = Integer.parseInt("42");
!
FileInputStream f =
new FileInputStream("datei");
}
}
Unhandled exception: java.io.FileNotFoundException
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
int a = Integer.parseInt("42");
!
try {
FileInputStream f =
new FileInputStream("datei");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
int a = Integer.parseInt("42");
!
try {
FileInputStream f =
new FileInputStream("datei");
int next = f.read();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Unhandled exception: java.io.IOException
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
try {
FileInputStream f =
new FileInputStream("datei");
int next = f.read();
} catch (IOException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
try {
FileInputStream f =
new FileInputStream("datei");
int next = f.read();
} catch (IOException|FileNotFoundException e) {
e.printStackTrace();
}
}
}
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
try {
FileInputStream f =
new FileInputStream("datei");
int next = f.read();
} catch (IOException|FileNotFoundException e) {
e.printStackTrace();
} finally {
f.close();
}
}
}
Unhandled exception: java.io.IOException
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
try (FileInputStream f =
new FileInputStream("datei")) {
int next = f.read();
} catch (IOException|FileNotFoundException e) {
e.printStackTrace();
}
}
}
AUSNAHMEN BEHANDELN II
int leseDatei() throws FileNotFoundException {
FileInputStream f = new FileInputStream("datei");
}
AUSNAHMEN ERZEUGEN
public class Wurm {
public class WurmLebenException extends
IllegalArgumentException {
}
!
private int leben;
!
public Wurm(int leben) {
if (leben <= 0) {
throw new WurmLebenException(
"Leben muss mehr als 0 sein");
}
!
this.leben = leben;
}
}
NEBENLÄUFIGKEIT
MAIN THREAD
Start
main-Methode im Main
Thread!
Anweisung 1
•
Sequentielle Ausführung
innerhalb jedes Threads!
Anweisung 2
•
Anweisungen blockieren &
warten
•
Anweisung 3
Ende
MEHRERE THREADS
Main Thread
•
•
•
Asynchrone Ausführung
von Main Thread und
Thread 2!
Gefahr bei Verwendung
gleicher Daten!
Anweisungen blockieren &
warten nur innerhalb eines
Threads
Start
Thread 2
Anweisung 1
Start
Anweisung 2
Anweisung 4
Anweisung 3
Ende
Anweisung 5
Ende
THREADS STARTEN
public class Spiel {
public static void main(String[] args) {
final String string = " du";
Thread t = new Thread(new Runnable() {
@Override
Closure
public void run() {
try {
„main-Methode“
des Threads
Thread.sleep(2000);
} catch (InterruptedException e) {
statische Methode
e.printStackTrace();
der Klasse Thread
}
(nicht mit dem Objekt
System.out.println(string);
t verwechseln!)
}
});
t.start();
System.out.print("Hallo");
}
}
JAVA 8
public class Spiel {
public static void main(String[] args) {
final String string = " du";
Thread t = new Thread(()-> {
Lambdatry {
Expression
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(string);
});
t.start();
System.out.print("Hallo");
}
}
ERGEBNIS?
Main Thread
Start
Thread 2
Starte Thread
$ java Spiel
Hallo du
Gebe
“Hallo“ aus
Ende
Start
Warte 2s
Gebe “ du“
aus
Ende
TIMING-PROBLEME
Korrektes Ergebnis?
public class Spiel {
public static void main(String[] args) {
DatenDownloader dd = new DatenDownloader();
dd.starteLangenDownloadAsynchron();
String ergebnis = dd.getErgebnis();
}
}
TIMING-PROBLEME
Lösung?
NEIN!!!!!
public class Spiel {
public static void main(String[] args) {
DatenDownloader dd = new DatenDownloader();
dd.starteLangenDownloadAsynchron();
Thread.sleep(2000);
String ergebnis = dd.getErgebnis();
}
}
CALLBACK
public interface DownloadListener {
public void fertig(String ergebnis);
}
public class DatenDownloader {
public void starteLangenDownload(DownloadListener l) {
new Thread(() -> {
// download...
String ergebnis = "ergebnis";
l.fertig(ergebnis);
}).start();
}
}
CALLBACK IMPLEMENTIEREN
public class Spiel {
public static void main(String[] args) {
DatenDownloader dd = new DatenDownloader();
dd.starteLangenDownload(new DownloadListener() {
@Override
public void fertig(String ergebnis) {
// verarbeite ergebnis
}
});
}
}
JAVA 8
LambdaExpression mit Parameter
public class Spiel {
public static void main(String[] args) {
DatenDownloader dd = new DatenDownloader();
dd.starteLangenDownload((String ergebnis) -> {
// verarbeite ergebnis
});
}
}
GEMEINSAM GENUTZTE
DATEN
•
•
Thread 1
Thread 2
Start
Start
konto1 -= 9
konto1 -= 2
konto2 += 9
konto2 += 2
Ende
Ende
konto1 = 10
konto2 = 0
public class Spiel {
static int konto1 = 10;
static int konto2 = 0;
!
static void transfer(int betrag) {
if (konto1 - betrag >= 0) {
// Zeit vergeht
konto1 -= betrag;
konto2 += betrag;
}
}
!
public static void main(String[] args) {
new Thread(() -> { transfer(2); }).start();
new Thread(() -> { transfer(9); }).start();
}
}
MÖGLICHE ERGEBNISSE
Gültig
konto1 = 1, konto2 = 9
Gültig
konto1 = 8, konto2 = 2
Ungültig konto1 = -1, konto2 = 11
public class Spiel {
static int konto1 = 10;
static int konto2 = 0;
!
!
static void transfer(int betrag) {
if (konto1 - betrag >= 0) {
// Zeit vergeht
konto1 -= betrag;
konto2 += betrag;
}
}
!
public static void main(String[] args) {
new Thread(() -> { transfer(2); }).start();
new Thread(() -> { transfer(9); }).start();
}
}
public class Spiel {
static int konto1 = 10;
static int konto2 = 0;
!
!
Spiel
während Methode gesperrt
synchronized static void transfer(int betrag) {
if (konto1 - betrag >= 0) {
// Zeit vergeht
konto1 -= betrag;
konto2 += betrag;
}
}
!
public static void main(String[] args) {
new Thread(() -> { transfer(2); }).start();
new Thread(() -> { transfer(9); }).start();
}
}
DEADLOCK
DEADLOCK
Thread 1
Thread 2
Sperre auf a
Sperre auf b
Sperre auf b
Sperre auf a
Entferne Sperre auf a
Entferne Sperre auf b
Entferne Sperre auf b
Entferne Sperre auf a
TEST DRIVEN DEVELOPMENT
TDD
•
Software in ständiger Metamorphose!
•
Tests zwingend erforderlich!
‣
•
Egal ob von Menschen oder automatisch!
Test Driven Development: Tests vor der
Implementierung implementieren
BOWLING GAME KATA
1
4
5
4
5
14
6
5
29
0
49
60
1
61
7
6
77
2
97
117
6
133
•
10 Frames!
•
Spare: 10 Pins in 2 Würfen: Nächster Wurf doppelt!
•
Strike: 10 Pins in 1 Wurf: Nächsten 2 Würfe doppelt!
•
Strike oder Spare im letzten Frame: 1-2 Würfe extra
ANFORDERUNGEN
•
Game Klasse!
‣
public void roll(int pins);
-
‣
Simuliert einen Wurf!
public int score();
-
Gibt die Gesamtpunktzahl zurück
BEGINN
•
•
Erstelle neues Projekt!
‣
File ➜ New Project ➜ Java!
‣
Name: BowlingGame!
Erstelle GameTest Klasse!
‣
Rechtsklick auf src ➜ New ➜ Java Class!
‣
Name: de.hhu.propra.bowlinggame.GameTest
BILDQUELLEN
Bild
Quelle
Exceptions,
Threads
http://geek-and-poke.com/
Deadlock
http://openbook.galileocomputing.de/javainsel9/bilder/
365_java_09_004.gif
TDD
http://www.projectcartoon.com/cartoon/353819
Herunterladen