Concurrency i Java – processer, kommunikation og synkronisering.

24
Concurrency i Java – processer, kommunikation og synkronisering
  • date post

    21-Dec-2015
  • Category

    Documents

  • view

    223
  • download

    0

Transcript of Concurrency i Java – processer, kommunikation og synkronisering.

Concurrency i Java – processer, kommunikation og

synkronisering

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.