Post on 21-Dec-2015
Michael E. Caspersen, 2001 PK2, F2001 concurrency.2
1. Oversigt
• Baggrund
• Concurrency i Java– tråde (Thread og Runnable)– Javas concurrency-model
• tilstande• operationer
– kritiske regioner (låsning)• synchronized• wait, notify, notifyAll• monitor, common class (readers/writers)
– Eksempler• konto• kommunikationskanal• Conways problem
Michael E. Caspersen, 2001 PK2, F2001 concurrency.3
Baggrund
• Motivation– speed-up– modellering– distribuering
• Historie– guldalder: 1965-75– flerbruger-operativsystemer– programmeringssprog
Michael E. Caspersen, 2001 PK2, F2001 concurrency.4
Tråde i Java (eksempel)class Traade {
static class Proces extends Thread { String name;
Proces(String name) { this.name = name; } int random(int i, int j) { ... } public void run() { for (int i=0; i!=10; ++i) { System.out.println(name); try {sleep(random(0,10)); } catch (InterruptedException e) {} } } }
public static void main(String[] args) { Proces a = new Proces("aa"); Proces b = new Proces("BBBB"); a.start(); b.start(); }}
Michael E. Caspersen, 2001 PK2, F2001 concurrency.5
Javas concurrency-model
Created Terminated Running Non-runnable Runnable
start
stop
yield
run
stop
stop/end
dispatch
sleep timeout
Depricated:- stop- suspend- resume
Men det skal I sådan set ikke tænke på!
Michael E. Caspersen, 2001 PK2, F2001 concurrency.6
Bankkundeclass Customer extends Thread { String name; Account a;
Customer(String name, Account a) { this.name = name; this.a = a; } int random(int i, int j) { ... }
public void run() { for (int i=0; i!=10; ++i) { int n = random(0,10); boolean succes = a.withdraw(n); System.out.println(name+": " + n + " sucess: "+succes); try { sleep(random(0,10)); } catch (InterruptedException e) {} } }}
Michael E. Caspersen, 2001 PK2, F2001 concurrency.7
Kontoclass Account { privte int amount = 0; public void insert(int i) { amount = amount + i; }
public boolean withdraw(int i) { if (amount > i) { amount = amount - i; return true; } else { return false; } }}
public static void main(String[] args) { Account ac = new Account(); ac.insert(50); Customer a = new Customer("aa",ac); Customer b = new Customer("BBBB",ac); a.start(); b.start();}
Michael E. Caspersen, 2001 PK2, F2001 concurrency.8
Sikker konto, synchronized
class Account { privte int amount = 0; public synchronized void insert(int i) { amount = amount + i; }
public synchronized boolean withdraw(int i) { if (amount > i) { amount = amount - i; return true; } else { return false; } }}
Udførelse af en synkroniseret metode bevirker at objektet (i dette tilfælde kontoen) låses så andre synkroniserede metoder på samme objekt ikke kan udføres samtidig!
Michael E. Caspersen, 2001 PK2, F2001 concurrency.9
Monitor
• Klasse med udelelige metoder
• Abstraktion der letter programmering med parallelle processer
• Ikke direkte understøttet i Java, men kan simuleres vha. synchronized
• Mange standardklasser i Java er (eller kanvha wrapperklasse instansieres som) monitorer– List data = Collections.synchronizedList(new LinkedList)
Michael E. Caspersen, 2001 PK2, F2001 concurrency.10
En kommunikationskanal (1)
class Channel { Object p; boolean empty = true;
synchronized public void transmit(Object p) { ??? this.p = p; empty = false; }
synchronized public Object receive() { ??? empty = true; return p; }}
Et synkroniseringsproblem...
Michael E. Caspersen, 2001 PK2, F2001 concurrency.11
En kommunikationskanal (2)
class Channel { Object p; boolean empty = true;
synchronized public void transmit(Object p) { await (empty); this.p = p; empty = false; }
synchronized public Object receive() { await (!empty); empty = true; return p; }}
En ”løsning” med await (ej Java)
Michael E. Caspersen, 2001 PK2, F2001 concurrency.12
En kommunikationskanal (3)
class Channel { Object p; boolean empty = true;
synchronized public void transmit(Object p) { while (!empty) { try { wait(); } catch (InterruptedException ie) {} } this.p = p; empty = false; notifyAll(); }
synchronized public Object receive() { while (empty) { try { wait(); } catch (InterruptedException ie) {} } empty = true; notifyAll(); return p; }}
Michael E. Caspersen, 2001 PK2, F2001 concurrency.13
Et modelleringseksempel
Edit Find
Adjust Collect
Produktion af avisspalter
SkrivemaskineIndlæser teksten en linie ad gangen
TokenizerOpdeler teksten i ord
BundtlerBundtler ord til linie
PrinterFordeler ekstra blanktegn mellem ordene på linien
Channel ofString
Channel ofString
Channel ofBunch
Michael E. Caspersen, 2001 PK2, F2001 concurrency.14
Hjælpeklasser
class Channel { synchronized public void transmit(Object p) { ... } synchronized public Object receive() { ... }}
class Bunch { int blanks; String[] words;
Bunch(int blanks, String[] words) { this.blanks = blanks; this.words = words; }
// i eksemplet tilgås blanks og words direkte!!! // men her kunne være get-metoder ...}
Michael E. Caspersen, 2001 PK2, F2001 concurrency.15
Hovedprogram
class Spalte {
public static void main(String[] args) { Channel ll = new Channel(); Channel ww = new Channel(); Channel bb = new Channel(); Edit er = new Edit("demo.txt",ll); Find fi = new Find(ll,ww); Collect co = new Collect(ww,bb,38); Adjust ad = new Adjust(bb); ad.start(); co.start(); fi.start(); er.start(); }}
Michael E. Caspersen, 2001 PK2, F2001 concurrency.16
Editclass Edit extends Thread { BufferedReader in; String inname; Channel out;
Edit(String inname, Channel out) { this.inname = inname; this.out = out; }
public void run() { try { in = new BufferedReader(new FileReader(inname)); while(in.ready()) { String s = in.readLine(); out.transmit(s); } in.close(); } catch (IOException e) {} }}
Michael E. Caspersen, 2001 PK2, F2001 concurrency.17
Find
class Find extends Thread {
Channel in; Channel out;
Find(Channel in, Channel out) { this.in = in; this.out = out; }
public void run() { while (true) { StringTokenizer s = new StringTokenizer((String) in.receive()," "); while (s.hasMoreTokens()) { out.transmit(s.nextToken()); } } }}
Michael E. Caspersen, 2001 PK2, F2001 concurrency.18
Collectclass Collect extends Thread { Channel in; Channel out; int col_width;
Collect(Channel in, Channel out, int col_width) { this.in = in; this.out = out; this.col_width = col_width; }
public void run() { String[] words = new String[col_width]; int no_chars = 0; int no_words = 0; while (true) { String s = (String) in.receive(); if (no_chars + no_words + s.length() > col_width) { String[] l = new String[no_words]; for (int i=0; i!=no_words; ++i) l[i] = words[i]; out.transmit(new Bunch(col_width-no_chars-no_words+1,l)); no_words = 0; no_chars = 0; } words[no_words] = s; ++no_words; no_chars = no_chars+s.length(); } }}
Michael E. Caspersen, 2001 PK2, F2001 concurrency.19
Adjust (1)
class Adjust extends Thread { Channel in;
Adjust(Channel in) { this.in = in; } int random(int i, int j) { ... }
public void run() { while (true) { Bunch b = (Bunch) in.receive(); String[] blanks = distribute(b); for (int i=0; i!= b.words.length; ++i) { System.out.print(b.words[i]); System.out.print(blanks[i]); } System.out.println(); } }}
Michael E. Caspersen, 2001 PK2, F2001 concurrency.20
Adjust (2)
String[] distribute(Bunch b) { String[] blanks = new String[b.words.length]; for (int i=0; i!=blanks.length-1; ++i) blanks[i] = " "; blanks[blanks.length-1] = ""; while (b.blanks>0) { int i = random(0,blanks.length-1); blanks[i] = blanks[i]+" "; --b.blanks; } return blanks; }
Michael E. Caspersen, 2001 PK2, F2001 concurrency.21
Kritik af monitorer
Monitor
Writer
Readers
. . .
En monitor sikrer gensidig udelukkelse på samtlige operationer, men det er ofte unødvendig forsigtigt.
Michael E. Caspersen, 2001 PK2, F2001 concurrency.22
Alternativ: Common class (1)
Monitor
Writer
Readers
. . .
Michael E. Caspersen, 2001 PK2, F2001 concurrency.23
Alternativ: Common class (2)
Monitor
Writer
Readers
. . .
Michael E. Caspersen, 2001 PK2, F2001 concurrency.24
Common Class
RWBuffer = common class var state nr, nw: integer; data item: T;
procedure entry write(e: T); begin entry: [when nw + nr = 0 do nw:= nw + 1] body: item:= e exit: [nw:= nw - 1] end;
procedure entry read(var e: T); begin entry: [when nw = 0 do nr:= nr + 1] body: e:= item exit: [nr:= nr - 1] end;
begin nr:= 0; nw:= 0; item:= ... end
entry- og exit-statements udføres udeleligt og med gensidig udelukkel-se i forhold til alle andre entry- og exit-statements i klassen.