Plan Trådbegrebet
Synkronisering
Koordinering
Eksempel: et flertrådet spil
En tråd er et sekventielt forløb i et program.
Java tillader flere tråde at eksistere på samme tid.
Tråde kan enten afvikles på en flerprocessor-maskine, eller (mere normalt) i simuleret parallel ved brug af tidsdeling. Trådbegrebet
Fordele:
Tillader hurtig reaktion på brugerinput Muliggør udvikling af reaktive systemer
Gør det muligt for en server at servicere flere klienter samtidigt Tråde Komplikationer:
Afbrydelse af en tråd kan efterlade et objekt i en inkonsistent tilstand (safety problem)
En tråd kan blokere andre tråde (liveness problem)
Tråde kan skabes og erklæres på to måder:
(1) ved nedarvning fra klassen Thread
(2) ved implementation af grænsefladen Runnable Skabelse af tråde
public class MyThread extends Thread {
public void run() {
// the thread body
}
// other methods and fields
} Nedarvning fra Thread Start af en tråd:
new MyThread().start();
Eksempel public class Counter1 extends Thread {
protected int count, inc, delay;
public Counter1(int init, int inc, int delay) {
this.count = init; this.inc = inc; this.delay = delay;
}
public void run() {
try {
for (;;) {
System.out.print(count + " ");
count += inc;
sleep(delay);
}
} catch (InterruptedException e) {}
}
public static void main(String[] args) {
new Counter1(0, 1, 33).start();
new Counter1(0, -1, 100).start();
}
}
public class MyThread extends AnotherClass
implements Runnable {
public void run() {
// the thread body
}
// other methods and fields
} Implementering af Runnable Start af en tråd:
new Thread(new MyThread()).start();
Eksempel public class Counter2 implements Runnable {
protected int count, inc, delay;
public Counter2(int init, int inc, int delay) {
this.count = init; this.inc = inc; this.delay = delay;
}
public void run() {
try {
for (;;) {
System.out.print(count + " ");
count += inc;
Thread.sleep(delay);
}
} catch (InterruptedException e) {}
}
public static void main(String[] args) {
new Thread(new Counter2(0, 1, 33)).start();
new Thread(new Counter2(0, -1, 100)).start();
}
}
En tråds livscyklus Alive New Dead run() returns Runnable start() Blocked yield() Wait to be
notified wait() notify()
notifyAll() Wait for target
to finish join() Target finish interrupt()
throws InterruptedException Sleeping sleep() Time out Not interrupted Interrupted interrupt()
Prioritering af tråde Enhver tråd er forsynet med en prioritet (et heltal imellem 1 og 10).
Prioriteter tildeles ved skabelsen. Som standard bliver prioriteten sat til prioriteten for den tråd, der skaber tråden. Prioriteter kan ændres dynamisk.
JVM vælger vilkårligt blandt de kørbare tråde, der har højst prioritet. Således vil tråde med en høj prioritet fortrænge (preempt) tråde med en lavere prioritet.
Afvikling af prioriterede tråde prioritet høj lav køreklare tråde
Retningslinjer for design Tråde, som skal reagere hurtigt på brugerinput, bør tildeles en høj prioritet.
Tråde med høj prioritet bør ikke varetage opgaver med lang udførelsestid.
Anvend kun prioriteter til at effektivisere et program. Et programs korrekthed må ikke afhænge af de involverede trådes prioriteter.
Synkronisering Mens et objekt bliver modificeret, kan det være i en inkonsistent tilstand.
Det er vigtigt at sikre, at andre tråde ikke tilgår objektet i denne situation.
Eksempel Implementeringen er korrekt ved kun én tråd; men ikke for flere tråde! public class Account {
// ...
public boolean withdraw(long amount) {
if (amount <= balance) {
long newBalance = balance - amount;
balance = newBalance;
return true;
}
return false;
}
private long balance;
}
Java garanterer, at læsning og skrivning af primitive
typer - med undtagelse af long og double - sker atomisk.
Alle andre operationer må synkroniseres eksplicit for at sikre atomicitet. Atomiske operationer
Kritiske regioner En kritisk region er et område af et program, som kun kan udføres af én tråd ad gangen.
Java anvender begrebet synkronisering til at specificere kritiske regioner i et program.
Synkronisering kan foretages på en metode eller på en blok af sætninger.
Synkronisering på metoder class MyClass {
synchronized void aMethod() {
«do something»
}
} Hele metodekroppen er en kritisk region.
Comments