Upload
eliot
View
44
Download
1
Embed Size (px)
DESCRIPTION
VPR - Repetition. Trådning Distribueret Programmering Sprogteori Grafer. Tråde. Tråd (lightweight process) Enkel sekventiel kontrolsekvens i et program Deler fælles data. Trådning. Fordele Overvågningssystemer med flere uafhængige opgaver Muliggør brugerinteraktion via BGF - PowerPoint PPT Presentation
Citation preview
VPG/Otto Knudsen 1
VPR - Repetition
Trådning Distribueret Programmering Sprogteori Grafer
VPG/Otto Knudsen 2
Tråde
Tråd (lightweight process) Enkel sekventiel kontrolsekvens i et
program Deler fælles data
VPG/Otto Knudsen 3
Trådning
Fordele Overvågningssystemer med flere
uafhængige opgaver Muliggør brugerinteraktion via BGF Muliggør serverhåndtering af flere
samtidige klienter Udnytter flerprocessor-systemer
optimalt
VPG/Otto Knudsen 4
Tråde
Ulemper Trådene afvikles uafhængigt af
hverandre Afviklingsrækkefølgen er vilkårlig Samspillet mellem tråde er ofte
meget kompleks Problemer med safety og liveness
VPG/Otto Knudsen 5
Instantiering af tråde
Tråde kan skabes på 2 måder: Arve fra Thread-klassen Implemetere Runnable-interfacet
VPG/Otto Knudsen 6
TrådeRunnable
Tråd
run()
Tråd
run()
overskrivesimplementeres
Thread
run() run()
VPG/Otto Knudsen 7
Thread-klassen
Skabe en tråd vha. Thread extends Thread-klassen Overskriv run-metoden Lav en instans af trådklassen Kald metoden start() på denne
instans
VPG/Otto Knudsen 8
Thread-klassen
class Tråd extends Thread {public void run() { kode }
}
...
new Tråd().start();
VPG/Otto Knudsen 9
Runnable-interfacet
Implements Runnable-interfacet implementér run-metoden Lav en instans af trådklassen Lav en ny Thread-instans med
Runnable-objektet som argument Kald metoden start() på denne
instans
VPG/Otto Knudsen 10
Runnable-interfacet
class Tråd implements Runnable {
public void run() { kode }
}
...
new Thread(new Tråd()).start();
VPG/Otto Knudsen 11
Runnable-interfacet
class Tråd implements Runnable {
public void run() { kode }
public void start() {
new Thread(this).start();
}
}
...
new Tråd().start();
VPG/Otto Knudsen 12
Trådes livscyklus
sleep()wait()blocked on sync
running
ready
blocked
Tråd
termineret
start()
new()
Kø af tråde
Tråden er "alive"
VPG/Otto Knudsen 13
Trådsikre klasser
Problem: Hvis en tråd afbrydes, medens den arbejder på et objekt, er der risiko for, at objektet efterlades i en inkonsistent tilstand. Dette kan give problemer, når en anden tråd forsøger at få tilgang til objektet
VPG/Otto Knudsen 14
Trådsikre klasser
Løsning: Løsningen er at forhindre mere end én tråd ad gangen i at få tilgang til de kritiske områder i koden Vha. synkronisering opnår en tråd eneret på
et objekt (lås) Låsen frigives, når tråden forlader det kritiske
område eller ved kald af metoden wait() på objektet. Kritiske områder på samme objekt deler samme lås!
VPG/Otto Knudsen 15
Liveness problemer Starvation (udhungring): En tråd, som er i
tilstanden ready, får aldrig lejlighed til at køre, fordi der findes andre tråde med højere prioritet
Dormancy (dvale): En tråd, som er i tilstanden blocked on wait, vækkes aldrig med notify()
Deadlock (hårdknude): To eller flere tråde kæmper om flere fælles ressourcer, og hver tråd efterspørger på samme tid disse ressourcer
Premature Termination (for tidlig død): En tråd termineres for tidligt og hindrer derved andre tråde i at blive vækket. (Evig dvale)
VPG/Otto Knudsen 16
volatile vs. synchronized Anvend volatile på en attribut, hvis denne
kan tilgås af flere tråde; med mindre at alle trådene tilgår attributten gennem synkroniserede metoder (kodeblokke)
Hvis flere tråde samtidigt kan tilgå en attribut, og mindst én af disse kan ændre i attributtens værdi, så er det generelt en god idé at anvende synchronized til at styre tilgangen
Hvis kun én tråd kan tilgå attributten, så er brugen afsynchronized overflødig og sløver programafviklingen
VPG/Otto Knudsen 17
Brug af synchronized Nødvendig, hvis man vil lave
"trådsikre klasser" Ej omkostningsfrit:
Kræver CPU-kraft langsommere programafvikling
"Hellere for mange synkroniserede blokke end for få!"MEN - pas på deadlocks
VPG/Otto Knudsen 18
Monitor En monitor indkapsler fælles
ressourcer som private attributter og sikrer trådene enetilgang vha. synchronized metoder til de kritiske områder
Formål: Overvågning af trådes adgang til fælles ressourcer Objekt, hvor de fælles ressourcer er samlet
(attributter) Der er udelelig adgang til monitorens
metoder (mutex) Én monitor-metode pr. kritisk sektion
VPG/Otto Knudsen 19
Missed notification Problemnotify sendes før wait
Konsekvensnotify mistes og wait-tråden bliver ved med at vente
LøsningSørg for kun at gå i wait, hvis notify endnu ikke er sendt. Sæt evt. en boolsk variabel, når notify sendes, og gå kun i wait, hvis denne variabel er sat
KonklusionSørg for at samle én begivenhed i ét synkroniseret monitorkald
VPG/Otto Knudsen 20
Early notification Problemnotify sendes før betingelserne for wait er opfyldt
Konsekvens wait-tråden vækkes før tid
LøsningCheck (igen) betingelserne for wait, når wait-tråden vækkes
KonklusionAnvend altid while (i stedet for if) i forbindelse med check af wait-betingelser
VPG/Otto Knudsen 21
Early notification1. Bufferen er tom!2. C1-tråden er i wait-tilstand3. P-tråden generer et nyt element og kalder monitorens
synkroniserede put-metode4. C1-tråden underrettes via notify, og tråden går i ready-
tilstand5. P-tråden forlader monitorens put-metode og slipper
objekt-låsen på monitoren6. Bufferen indeholder nu ét element!7. Trådskifte!8. C2-tråden trækker et element fra bufferen ved at kalde
monitorens get-metode9. C2-tråden forlader monitorens get-metode og slipper
objekt-låsen på monitoren10. Der er ingen elementer i bufferen!11. Trådskifte!12. C1 fortsætter nu fra wait i monitorens get-metode i
forsøget på at trække endnu et element fra bufferen … Dette er ikke muligt!
P
C 1
Bu ffe r
C 2
VPG/Otto Knudsen 22
Guarded Suspensionpublic synchronized void put(String data) throws InterruptedException {
while (buffer.isFull()) // while i stedet for ifthis.wait();
if (buffer.isEmpty())this.notify();buffer.add(data);
}
public synchronized String get() throws InterruptedException {while (buffer.isEmpty()) // while i stedet for if
this.wait();if (buffer.isFull())
this.notify();String data = (String)buffer.remove();return data;
}
VPG/Otto Knudsen 23
Observer PatternObservable
addObserversetChangednotifyObservers
Observer
update
1 N
Subjekttilstand
getTilstand
Observatørtilstand
update
1 N
Eks: Model/View
public void notifyObservers(Object data) { ... // for alle associerede observatør-objekter o, gør flg: o.update(this, data); ...}
public void update(Observable source, Object data) { // kan fx indeholde flg. kode: this.tilstand = source.getTilstand();}
public void addObserver(Observer o)// tilføjer et observatør-objekt til associasionslisten
Abstrakt niveau
Konkret niveau
extends Observable implements Observer
<<interface>>Abstrakt klasse
VPG/Otto Knudsen 24
Distribueret Programmering
Sockets RMI CORBA (ej pensum) JDBC (ej pensum)
VPG/Otto Knudsen 25
Sockets Sockets er logiske endepunkter i en forbindelse mellem
server og klient På applikationsniveauet betragtes Sockets som
”pålidelige”, dvs. data som sendes fra den ene ende af forbindelsen modtages i den anden ende i samme rækkefølge, som de er sendt, og uden tab
Sockets optræder parvis – klienten har en Socket til serveren og omvendt
En Socket er tilknyttet både en InputStream OutputStream
Klientens OutputStream er forbundet til serverens InputStream og omvendt
VPG/Otto Knudsen 26
Sockets - Arkitektur
Socket Socket
Server Klient
InputStream
OutputStream InputStream
OutputStream
fx port 2000
VPG/Otto Knudsen 27
Sockets - Serversiden1. Skab en ServerSocket på portnr 2000 (fx)
try {ServerSocket s = new ServerSocket(2000);
} catch (IOException e) {}
2. Vent på forespørgsel fra klientwhile (true) {
Socket socket = s.accept();}
3. Skab InputStream og OutputStream ud fra SocketBufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
4. Send og modtag via InputStream og OutputStreamin.read();out.println();
5. Luk strømme og Sockets
VPG/Otto Knudsen 28
Sockets - Klientsiden1. Skab en Socket til serveren vha. hostname og portnr
try {Socket s = new Socket(”localhost”, 2000);
} catch(IOException e) {}
2. Skab InputStream og OutputStream ud fra SocketBufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
3. Send og modtag via InputStream og OutputStreamin.read();out.println();
4. Luk strømme og Socket
VPG/Otto Knudsen 29
Sockets - StrømmeReader
InputStream InputStreamReader BufferedReader
FileReader
Writer
OutputStream OutputStreamWriter BufferedWriter
FileWriter
PrintWriter
VPG/Otto Knudsen 30
Flere samtidige klienter Server
class Server {public static void main(String[] args) {
try { ServerSocket s = new ServerSocket(2000); while (true) { // Vent på anmodning fra klient ... Socket socket = s.accept(); // Instantiér klienttråd - og start den ... new ClientHandler(socket).start(); } } catch (IOException e) {}
}}
VPG/Otto Knudsen 31
Flere samtidige klienterClientHandler
class ClientHandler extends Thread {private Socket incoming;public ClientHandler(Socket incoming) {
this.incoming = incoming; }
public void run() { try { // Instantiér ind- og ud-strøm while (true) { // Kommunikér } } catch (IOException e) {}
}}
VPG/Otto Knudsen 32
RMI RMI (Remote Method Invocation)
Kald af metoder på serverobjekt fra klient Filosofi
Objekter på serveren gøres tilgængelige på klienten
Abstraktionsniveau Højere abstraktionsniveau end Sockets Objektorienteret – Syntaksen svarer til almindelig Java Fælles data og funktionalitet Transparens – Der arbejdes med serverobjekterne,
som om de lå på klienten Miljø
RMI findes kun til Java
VPG/Otto Knudsen 33
RMI - Arkitektur
Klient
Stub
JVM
Server
Skeleton
JVM
1 6 3
2
5
4
VPG/Otto Knudsen 34
RMI - Arkitektur1. Kald af metoden server.metode() fra klienten
udføres som et metodeklad på stub’en: stub.metode()
2. Stub’en arrangerer argumenterne i metodekaldet, (marshalling), og sender dem til skeleton’en på serveren tillige med information om kaldet
3. Skeleton’en afkoder argumenterne samt informationen om kaldet, (demarshalling), og kalder metoden på serveren: server.metode()
4. Serverobjektet eksekverer metodekaldet og sender eventuel en returværdi til skeleton’en
5. Skeleton’en arrangerer returværdien, (marshalling), og sender resultatet til stub’en
6. Stub’en afkoder, (demarshalling), returværdien og returnerer den til klienten
VPG/Otto Knudsen 35
RMI – Begreber Marshalling
Arrangering af information om metodekald, dvs. objekt-id, metodenavn, argumenter og returværdier
Lokale objekterObjekter, som kun kan tilgås lokalt, enten på serveren eller på klienten.Lokale objekter, der overføres som argumenter eller returværdier skal implementere markør-interfacet Serializable
Remote objekterObjekter, som er tilgængelige fra andre maskiner/processer.Remote objekter skal implementere markør-interfacet Remote
Remote referenceReference til et objekt, der fysisk er placeret på en anden maskine/proces. Referencen indeholder ip-adresse, portnr samt objekt-id på serverobjektet
Remote metodekaldKald af servermetode fra klient. Ved remote metodekald overføres lokale objekter by value og remote objekter by reference
VPG/Otto Knudsen 36
RMI – Proxy-mønsteret<<interface>>KontoServerI
+indsaet(beloeb:float):float+haev(beloeb:float):float+getSaldo():float
Klient
+main(args)
KontoServer
-kontonr-saldo
implements implements
Proxy
uses
remote reference
ServerKlient
VPG/Otto Knudsen 37
RMI - Serversidenimport java.rmi.*;public interface Konto extends Remote {
... // metodeerklæringerpublic double indsaet(double beloeb) throws RemoteException;
}
import java.rmi.*;import java.rmi.server.UnicastRemoteObject;public class KontoServer extends UnicastRemoteObject implements Konto {
... // attributterdouble saldo;public KontoServer() throws RemoteException {
super();saldo = 0.0;
}... // metodeimplementeringerpublic double indsaet(double beloeb) throws RemoteException {
saldo += beloeb;return saldo;
}}
VPG/Otto Knudsen 38
RMI - Kontoeksemplet
Ko n to k lie n t Ko n to
Ko n to Se rve r_ Stu b Ko n to Se rve r
haev ()indsaet()
haev ()indsaet()
haev ()indsaet()
Ko n to k lie n t Un ica s tR e mo te O b je c t
Proxy Pattern
Eksempel
Klie n t Su b je ct
R e a lO b je c t Pro xy
VPG/Otto Knudsen 39
Forløbet af et RMI-kald (1)1. Definér et interface (kontrakt) til et remote objekt
public interface Konto extends java.rmi.Remote {...public double indsaet(double beloeb) throws RemoteException;
}
2. Implementér ovenstående interface på serversidenpublic class KontoServer extends
java.rmi.server.UnicastRemoteObject implements Konto {...public double indsaet(double beloeb) throws RemoteException;
}
VPG/Otto Knudsen 40
Forløbet af et RMI-kald (2)3. Skab en instans af NameServer-objektet på en given
port (fx 1099) vha. LocateRegistryjava.rmi.registry.LocateRegistry.createRegistry(1099);
4. Skab en instans af serveren og registrér serveren i RMI-registry
Konto server = new KontoServer();java.rmi.Naming.rebind("Konto", server);
5. Generér stub og skeleton class-filer vha. RMI-compileFilerne får navnene KontoServer_Stub.class og KontoServer_Skeleton.classStub-klassen implementerer også Konto-interfacet
VPG/Otto Knudsen 41
Forløbet af et RMI-kald (3)6. Lokalisér remote objektet – konto er nu en instans af
stub-klassen, som implementerer Konto-interfacetKonto konto = (Konto)java.rmi.Naming.lookup("//localhost:1099/Konto")
7. Lav en klient, som anvender metoderne på konto-objektet:
konto.indsaet(100);
VPG/Otto Knudsen 42
RMI – MathInterfacepackage math;
import java.rmi.*;
public interface MathInterface extends Remote {public int add(int a, int b) throws RemoteException;public int sub(int a, int b) throws RemoteException;public int mul(int a, int b) throws RemoteException;public int div(int a, int b)
throws RemoteException, ArithmeticException;}
VPG/Otto Knudsen 43
RMI - MathServerpackage math;
import java.rmi.*;import java.rmi.server.*;
public class MathServer extends UnicastRemoteObject implements MathInterface {
public MathServer() throws RemoteException {}public int add(int a, int b) throws RemoteException{return a + b;}public int sub(int a, int b) throws RemoteException{return a - b;}public int mul(int a, int b) throws RemoteException{return a * b;}public int div(int a, int b)
throws RemoteException, ArithmeticException {return a / b;}}
VPG/Otto Knudsen 44
RMI - Serverpackage math;
import java.rmi.*;import java.rmi.registry.*;
public class Server {public static void main(String[] args) {
try { LocateRegistry.createRegistry(1099); Naming.bind("Math", new MathServer()); System.out.println("Serveren er
registreret");} catch (RemoteException e) {System.exit(1);}
}}
VPG/Otto Knudsen 45
RMI - Klientpackage math;
import java.rmi.*;
public class MathClient {public static void main(String[] args) { MathInterface math = null; try { math = (MathInterface)Naming.lookup("Math"); System.out.println("1 + 2 = " + math.add(1, 2)); System.out.println("3 + 4 = " + math.add(3, 4)); System.out.println("5 + 6 = " + math.add(5, 6)); System.out.println("7 + 8 = " + math.add(7, 8)); } catch (Exception e) {System.exit(1);}}
}