57
Semin ´ r Java Paralelismus Radek Koˇ ı Fakulta informaˇ cn´ ıch technologi´ ı VUT rezen 2012 Radek Koˇ ı Semin ´ r Java – Paralelismus 1/ 55

Semin r Java - Paralelismus

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Semin r Java - Paralelismus

Seminar JavaParalelismus

Radek Kocı

Fakulta informacnıch technologiı VUT

Brezen 2012

Radek Kocı Seminar Java – Paralelismus 1/ 55

Page 2: Semin r Java - Paralelismus

Obsah

Vlakna

Multithreading

Sdılenı prostredku

Synchronizace

Radek Kocı Seminar Java – Paralelismus 2/ 55

Page 3: Semin r Java - Paralelismus

Pojmy

Proces

spusteny program s vlastnım adresovym prostorem

Vlakno (podproces)

nezavisla vedlejsı uloha

spustena v kontextu procesu

sdılı adresovy prostor procesu

Multithreading

technika rozdelenı behu programu na vıce podprocesu

typicky pro oddelenı castı programu, ktere jsou vazane na

prostredky

Radek Kocı Seminar Java – Paralelismus 3/ 55

Page 4: Semin r Java - Paralelismus

Proces a vlakna

Process

Threads

Radek Kocı Seminar Java – Paralelismus 4/ 55

Page 5: Semin r Java - Paralelismus

Vlakna

vlakna jsou reprezentovana objekty

kazde vlakno ma svuj jedinecny identifikator (pridelen pri

vytvorenı)

vlakno muze mıt svuj nazev

Radek Kocı Seminar Java – Paralelismus 5/ 55

Page 6: Semin r Java - Paralelismus

Prace s vlakny

Balık java.lang

Thread

Runnable

Reprezentace vlakna

instance trıdy Thread (ev. odvozenych trıd)

Vytvorenı objektu, ktery reprezentuje beh vlakna

rozsırenım (dedicnost) trıdy Thread

implementacı rozhranı Runnable

Radek Kocı Seminar Java – Paralelismus 6/ 55

Page 7: Semin r Java - Paralelismus

Trıda Thread

Metody

start()

inicializace vlaknavola metodu run()

odvozena trıda neprekryva tuto metodu!

run()

kod vlaknaodvozena trıda prekryva tuto metodu

sleep(long millis)

uspanı vlakna na dany pocet milisekundvyjimka InterruptedException

Radek Kocı Seminar Java – Paralelismus 7/ 55

Page 8: Semin r Java - Paralelismus

Ukazka SimpleThread

public class SimpleThread extends Thread {

public SimpleThread(String str) {

super(str);

}

public void run() {

for (int i = 0; i < 10; i++) {

System.out.println(i + " " + getName());

try {

sleep((long)(Math.random() * 1000));

} catch (InterruptedException e) {}

}

System.out.println("DONE! " + getName());

}

}

Radek Kocı Seminar Java – Paralelismus 8/ 55

Page 9: Semin r Java - Paralelismus

Ukazka SimpleThread

public class TwoThreadsDemo {

public static void main (String[] args) {

new SimpleThread("Jamaica").start();

new SimpleThread("Fiji").start();

}

}

Radek Kocı Seminar Java – Paralelismus 9/ 55

Page 10: Semin r Java - Paralelismus

Rozhranı Runnable

Metody

run()

kod vlaknaimplementujıcı trıda musı implementovat tuto metodu

Implementujıcı trıda

nenı vlakno

informace, ze instance trıdy definuje chovanı vlakna

pro spustenı vlakna potrebuje trıdu Thread

Radek Kocı Seminar Java – Paralelismus 10/ 55

Page 11: Semin r Java - Paralelismus

Ukazka Clock

public class Clock extends Applet

implements Runnable {

private Thread clockThread = null;

public void start() {

if (clockThread == null) {

clockThread = new Thread(this, "Clock");

clockThread.start();

}

}

public void paint(Graphics g) {

//get the time and convert it to a date

...

g.drawString(dateFormatter.format(date), 5, 10);

}

Radek Kocı Seminar Java – Paralelismus 11/ 55

Page 12: Semin r Java - Paralelismus

Ukazka Clock

public void run() {

Thread myThread = Thread.currentThread();

while (clockThread == myThread) {

repaint();

try { Thread.sleep(1000); }

catch (InterruptedException e) {

//the VM doesn’t want us to sleep anymore,

//so get back to work

}

}

}

//overrides Applet’s stop method, not Thread’s

public void stop() {

clockThread = null;

}

}

Radek Kocı Seminar Java – Paralelismus 12/ 55

Page 13: Semin r Java - Paralelismus

Trıda Thread nebo rozhranı Runnable

hodne trıd potrebuje dedit (rozsirovat) jinou trıdu

public class Clock extends Applet

implements Runnable {...

}

Java neumoznuje vıcenasobnou dedicnost

⇒ rozhranı Runnable

clockThread = new Thread(this, "Clock");

clockThread.start();

Radek Kocı Seminar Java – Paralelismus 13/ 55

Page 14: Semin r Java - Paralelismus

Zivotnı cyklus vlakna

New Thread

Dead

Not RunnableRunnable

start

The run method terminates

runnable

yield

Radek Kocı Seminar Java – Paralelismus 14/ 55

Page 15: Semin r Java - Paralelismus

Zivotnı cyklus vlakna

Vytvorenı

new Thread(this, "Clock")

Spustenı

start()

kod vlakna v metode run() (Thread nebo Runnable)

Ukoncenı

prirozenym dobehnutım metody run()

existujı i jine metody, ty se ale nedoporucujı (deprecated)

stop()

destroy()

suspend(), resume()

Radek Kocı Seminar Java – Paralelismus 15/ 55

Page 16: Semin r Java - Paralelismus

Zivotnı cyklus vlakna

Test stavu vlakna

isAlive()

⇒ true pokud bylo vlakno spusteno a nebylo ukonceno

(nenı dead)

⇒ false pokud vlakno nebylo spusteno, nebo bylo

ukonceno (je dead)

Radek Kocı Seminar Java – Paralelismus 16/ 55

Page 17: Semin r Java - Paralelismus

Zivotnı cyklus vlakna

Pozastavenı (stav not runnable)

sleep(...)

wait()

pri i/o operaci

Uvolnenı (stav runnable)

uplynutı doby cekanı (viz sleep(...))

notify(), notifyAll()

dokoncenı pri i/o operace

Radek Kocı Seminar Java – Paralelismus 17/ 55

Page 18: Semin r Java - Paralelismus

Vlakna

Chovanı vlaken zavisı na jejich internı reprezentaci.

Native threads

vlakna operacnıho systemu

vıce procesoru

preemtivnı planovanı

Green threads

vlakna na urovni JVM

jeden procesor

vlakno se musı prepnout samo

jiz nejsou moc bezna

Radek Kocı Seminar Java – Paralelismus 18/ 55

Page 19: Semin r Java - Paralelismus

Planovanı vlaken

Jedna CPU

provadenı vlaken se musı planovat

planovac v Jave je fixed-priority scheduling

planuje vlakna na zaklade jejich priority relativne k

ostatnım vlaknum

Priorita

vlakno dedı prioritu vlakna, ve kterem bylo vytvoreno

ctenı/zmena priority: getPriority(), setPriority()

rozsah: Thread.MIN PRIORITY –

Thread.MAX PRIORITY

Radek Kocı Seminar Java – Paralelismus 19/ 55

Page 20: Semin r Java - Paralelismus

Planovanı vlaken

Planovac

vybere vlakno (runnable) s nejvyssı prioritou

pokud je jich vıce se stejnou prioritou, vybere

nahodne/spravedlive

Vlakno bezı dokud se nestane:

na systemu s time-slicing ubehne pridelene casove

kvantum

jine vlakno s vyssı prioritou prejde do stavu runnable

skoncı metoda run()

vlakno se vzda procesoru

vlakno se dobrovolne vzda procesoru – zprava yield()

⇒ sance pro ostatnı vlakna na stejne priorite

Radek Kocı Seminar Java – Paralelismus 20/ 55

Page 21: Semin r Java - Paralelismus

Thread

Thread Thread.currentThread()

vratı prave bezıcı vlakno (objekt)

setName / getName

kazde vlakno muze mıt sve jmeno

long getId()

kazde vlakno ma svuj jedinecny identifikator

Thread.State getState()

vracı stav vlakna

enum Thread.State

Radek Kocı Seminar Java – Paralelismus 21/ 55

Page 22: Semin r Java - Paralelismus

Thread

enum Thread.State

NEW – vlakno pouze vytvoreno

RUNNABLE – bezıcı vlakno

BLOCKED – vlakno ceka na monitoru

WAITING – vlakno ceka na jine vlakno / operaci (casove

neomezeno)

TIMED WAITING – vlakno ceka na jine vlakno (casove

omezeno)

TERMINATED – vlakno bylo ukonceno

Radek Kocı Seminar Java – Paralelismus 22/ 55

Page 23: Semin r Java - Paralelismus

Thread – stavy vlakna

WAITING

Object.wait()

Thread.join()

LockSupport.park()

I/O operace

TIMED WAITING

Object.wait(long)

Thread.join(long)

Thread.sleep(long)

LockSupport.parkNanos(long)

LockSupport.parkUntil(long)

java.util.concurrent.locks.LockSupport

Radek Kocı Seminar Java – Paralelismus 23/ 55

Page 24: Semin r Java - Paralelismus

Skupina vlaken

java.lang.ThreadGroup

vlakno patrı vzdy k nejake skupine

existuje implicitnı systemova skupina

skupiny tvorı stromovou hierarchii

prıslusnost ke skupine je nemenna

vlakno implicitne ”dedı” skupinu vytvarejıcıho vlakna

Thread.currentThread().getThreadGroup()

Radek Kocı Seminar Java – Paralelismus 24/ 55

Page 25: Semin r Java - Paralelismus

Synchronizace vlaken

Problem producent–konzument

jedno vlakno (producent) zapisuje na sdılene mısto data

druhe vlakno (konzument) tato data cte

operace zapis/ctenı se musı strıdat!

Ukazkovy prıklad

trıda Producer – producent

trıda Consumer – konzument

trıda CubbyHole – sdıleny prostor (metody get a put)

Radek Kocı Seminar Java – Paralelismus 25/ 55

Page 26: Semin r Java - Paralelismus

Producent–konzument: Producent

public class Producer extends Thread {

private CubbyHole cubbyhole;

public Producer(CubbyHole c) {

cubbyhole = c;

}

public void run() {

for (int i = 0; i < 10; i++) {

cubbyhole.put(i);

try {

sleep((int)(Math.random() * 100));

} catch (InterruptedException e) { }

}

}

}

Radek Kocı Seminar Java – Paralelismus 26/ 55

Page 27: Semin r Java - Paralelismus

Producent–konzument: Konzument

public class Consumer extends Thread {

private CubbyHole cubbyhole;

public Consumer(CubbyHole c) {

cubbyhole = c;

}

public void run() {

int value = 0;

for (int i = 0; i < 10; i++) {

value = cubbyhole.get();

}

}

}

Radek Kocı Seminar Java – Paralelismus 27/ 55

Page 28: Semin r Java - Paralelismus

Producent–konzument: CubbyHole

public class CubbyHole {

private int contents;

public int get() {

return contents;

}

public int put(int value) {

contents = value;

}

}

Radek Kocı Seminar Java – Paralelismus 28/ 55

Page 29: Semin r Java - Paralelismus

Producent–konzument: mozne problemy

Producent je rychlejsı

konzument muze ”propasnout” cısla

Konzumer je rychlejsı

konzument cte stejne cıslo vıcekrat

⇒ race condition

dve (prıp. vıce) vlakna ctou/zapisujı sdılena data; vysledek

zavisı na casovanı (jak jsou vlakna planovana)

Radek Kocı Seminar Java – Paralelismus 29/ 55

Page 30: Semin r Java - Paralelismus

Producent–konzument: mozne problemy

⇒ race condition

dve (prıp. vıce) vlakna ctou/zapisujı sdılena data; vysledek

zavisı na casovanı (jak jsou vlakna planovana)

Nutna synchronizace:

vlakna nesmı soucasne pristoupit ke sdılenemu objektu

producent musı indikovat, ze hodnota je pripravena;

nezapisuje dokud si hodnotu neprecte konzument

konzument musı indikovat, ze precetl hodnotu; necte

dokud producent nezapıse novou hodnotu

Radek Kocı Seminar Java – Paralelismus 29/ 55

Page 31: Semin r Java - Paralelismus

Monitor

Monitor

kriticke sekce

uzamcenı objektu pri prıstupu ke kriticke sekci

pokud je objekt uzamcen, nikdo jiny nemuze pristupovat je

kritickym sekcım objektu

odemknutı objektu pri vystupu z kriticke sekce

Monitor v Jave (intrinsic lock)

soucastı kazdeho objektu (trıda Object)

klıcove slovo synchronized

Kriticka sekce v Jave

metoda

blok

Radek Kocı Seminar Java – Paralelismus 30/ 55

Page 32: Semin r Java - Paralelismus

Producent–konzument: CubbyHole

public class CubbyHole {

private int contents;

private boolean available = false;

public synchronized int get() {

//CubbyHole locked by the Producer

...

// CubbyHole unlocked by the Producer

}

public synchronized int put(int value) {

// CubbyHole locked by the Consumer

...

// CubbyHole unlocked by the Consumer

}

}

Radek Kocı Seminar Java – Paralelismus 31/ 55

Page 33: Semin r Java - Paralelismus

Zamek: reentrantnı

public class Reentrant {

public synchronized void a() {

b();

System.out.println("here I am, in a()");

}

public synchronized void b() {

System.out.println("here I am, in b()");

}

}

Radek Kocı Seminar Java – Paralelismus 32/ 55

Page 34: Semin r Java - Paralelismus

Producent–konzument: CubbyHole

public class CubbyHole {

private int contents;

private boolean available = false;

public synchronized int get() {

if (available == true) {

available = false;

return contents;

}

}

public synchronized int put(int value) {

if (available == false) {

available = true;

contents = value;

}

}

}

Radek Kocı Seminar Java – Paralelismus 33/ 55

Page 35: Semin r Java - Paralelismus

Producent–konzument: synchronizace

Nutna synchronizace:

vlakna nesmı soucasne pristoupit ke sdılenemu objektu

producent musı indikovat, ze hodnota je pripravena

konzument musı indikovat, ze precetl hodnotu

producent nezapisuje dokud si hodnotu neprecte

konzument

konzument necte dokud producent nezapıse novou

hodnotu

Radek Kocı Seminar Java – Paralelismus 34/ 55

Page 36: Semin r Java - Paralelismus

Producent–konzument: synchronizace

Nutna synchronizace:

vlakna nesmı soucasne pristoupit ke sdılenemu objektu

producent musı indikovat, ze hodnota je pripravena

konzument musı indikovat, ze precetl hodnotu

producent nezapisuje dokud si hodnotu neprecte

konzument

konzument necte dokud producent nezapıse novou

hodnotu

Radek Kocı Seminar Java – Paralelismus 34/ 55

Page 37: Semin r Java - Paralelismus

Synchronizace vlaken (trıda Object)

wait()

aktualnı vlakno bude cekat, dokud se nezavola notify()

(notifyAll()) nad objektem

wait(long timeout)

. . . nebo neuplyne timeout

notify()

vzbudı jedno vlakno cekajıcı na monitoru objektu

notifyAll()

vzbudı vsechna vlakna cekajıcı na monitoru objektu

Radek Kocı Seminar Java – Paralelismus 35/ 55

Page 38: Semin r Java - Paralelismus

Synchronizace vlaken (trıda Object)

wait(), ...

pred suspendovanım vlakna se odemkne monitor

pokud vlakno vlastnı vıce monitoru, odemkne se pouze

monitor daneho objektu

notify(), ...

rızenı nenı okamzite predano vzbuzenemu vlaknu

Tyto metody muze volat pouze to vlakno, ktere je vlastnıkem

monitoru

vstoupenı do kriticke sekce (synchronized) – metoda,

blok

Radek Kocı Seminar Java – Paralelismus 36/ 55

Page 39: Semin r Java - Paralelismus

Producent–konzument: CubbyHole

public synchronized int get() {

while (available == false) {

try {

// wait for Producer to put value

wait();

} catch (InterruptedException e) { }

}

available = false;

// notify Producer that value has been

// retrieved

notifyAll();

return contents;

}

Radek Kocı Seminar Java – Paralelismus 37/ 55

Page 40: Semin r Java - Paralelismus

Producent–konzument: CubbyHole

public synchronized void put(int value) {

while (available == true) {

try {

// wait for Consumer to get value

wait();

} catch (InterruptedException e) { }

}

contents = value;

available = true;

// notify Consumer that value has been set

notifyAll();

}

Radek Kocı Seminar Java – Paralelismus 38/ 55

Page 41: Semin r Java - Paralelismus

Synchronizace vlaken – efektivita

Pri uzamcenı objektu se zvysı naklady na rezii

uvazit zmenu navrhu

pouzıt zamek (synchronized) na konkretnı objekt

neodbyt soubezny prıstup synchronizacı vsech metod

Radek Kocı Seminar Java – Paralelismus 39/ 55

Page 42: Semin r Java - Paralelismus

Synchronizace vlaken

Blok jako kriticka sekce

stejny princip synchronizace

metody se nemusı deklarovat jako synchronizovane

deklaruje se objekt, jehoz monitor se pouzije pri obsluze

kriticke sekce

synchronized(cybbyhole) {cybbyhole.put(i);

}synchronized(cybbyhole) {

value = cybbyhole.get();

}

Radek Kocı Seminar Java – Paralelismus 40/ 55

Page 43: Semin r Java - Paralelismus

Prerusenı vlakna

Operace interrupt() (Thread)

je nastaven prıznak

prerusitelne operace (sleep(), ...) testujı tento prıznak

Vlakno je bezıcı

pouze se nastavı prıznak

lze otestovat (isInterrupted())

Vlakno je cekajıcı

je nastaven prıznak

vlakno se rozbehne a vygeneruje se vyjimka

(InterruptedException)

Radek Kocı Seminar Java – Paralelismus 41/ 55

Page 44: Semin r Java - Paralelismus

Viditelnost promenne

Viditelnost sdılene promenne

zmena hodnoty se nemusı projevit okamzite (optimalizace)

⇒ klıcove slovo volatile

Radek Kocı Seminar Java – Paralelismus 42/ 55

Page 45: Semin r Java - Paralelismus

Proc nepouzıvat stop() a suspend()?

stop()

uvolnı vsechny monitory blokovane vlaknem

nebezpecı prıstupu k objektum v nekonzistentnım stavu

⇒ prirozene ukoncenı metody run()

suspend(), resume()

suspenduje/uvolnı vlakno

suspendovane vlakno drzı monitor (viz kriticka sekce);

vlakno, ktere ho ma uvolnit (viz resume), musı vstoupit do

teto sekce ⇒ dead-lock

⇒ wait(), notify()

vıce na

http://java.sun.com/j2se/1.5.0/docs/guide/misc/

threadPrimitiveDeprecation.html

Radek Kocı Seminar Java – Paralelismus 43/ 55

Page 46: Semin r Java - Paralelismus

Explicitnı zamky

java.util.concurrent.locks

rozhranı Lock, Condition, ReadWriteLock

trıdy ReentrantLock, ReentrantReadWriteLock

trıda ReentrantReadWriteLock.ReadLock

trıda ReentrantReadWriteLock.WriteLock

Radek Kocı Seminar Java – Paralelismus 44/ 55

Page 47: Semin r Java - Paralelismus

Lock

public interface Lock {

void lock();

void lockInterruptibly()

throws InterruptedException;

boolean tryLock();

boolean tryLock(long timeout, TimeUnit unit)

throws InterruptedException;

void unlock();

Condition newCondition();

}

Radek Kocı Seminar Java – Paralelismus 45/ 55

Page 48: Semin r Java - Paralelismus

ReentrantLock implements Lock

Lock lock = new ReentrantLock();

lock.lock();

try {

...

} finally {

lock.unlock();

}

Radek Kocı Seminar Java – Paralelismus 46/ 55

Page 49: Semin r Java - Paralelismus

Lock a Condition

public interface Condition {

void await() throws InterruptedException;

boolean await(long time, TimeUnit unit)

throws InterruptedException;

long awaitNanos(long nanosTimeout)

throws InterruptedException;

void awaitUninterruptibly()

throws InterruptedException;

long awaitUntil(Date deadline)

throws InterruptedException;

void signal();

void signalAll();

}

Radek Kocı Seminar Java – Paralelismus 47/ 55

Page 50: Semin r Java - Paralelismus

Vztah zamku a JVM

Intrinsic locks

mene flexibilnı

JVM vı o vztahu vlakna a zamku

Explicit locks

flexibilnı

JVM nevı o vztahu vlakna a zamku

Radek Kocı Seminar Java – Paralelismus 48/ 55

Page 51: Semin r Java - Paralelismus

Synchronizovane struktury

java.util.concurrent

BlockingQueue

SynchronousQueue

Semaphore

. . .

private BlockingQueue cubbyhole;

cubbyhole.put(i);

...

Radek Kocı Seminar Java – Paralelismus 49/ 55

Page 52: Semin r Java - Paralelismus

Synchronizovane kolekce

Staticke metody trıdy Collections

XXX synchronizedXXX(XXX c);

Collection synchronizedSet(Collection c);

Map synchronizedMap(Map c);

. . .

Radek Kocı Seminar Java – Paralelismus 50/ 55

Page 53: Semin r Java - Paralelismus

Synchronizovane kolekce

public class SynchronDemo {

public static void main(String[] args) {

List seznam = new ArrayList();

seznam.add(new Integer(20));

...

Iterator i = seznam.iterator();

// Simulace soubezne akce jineho vlakna!!

seznam.remove(new Integer(20));

// ...

Integer c = (Integer) i.next();

}

}

Vyjimka ConcurrentModificationException

Radek Kocı Seminar Java – Paralelismus 51/ 55

Page 54: Semin r Java - Paralelismus

Synchronizovane kolekce

Synchronization wrapper

public class SynchronDemo2 {

public static void main(String[] args) {

List seznam = Collections.

synchronizedList(new ArrayList());

seznam.add(new Integer(20));

synchronized(seznam) {

Iterator i = seznam.iterator();

Integer c = (Integer) i.next();

}

}

}

Radek Kocı Seminar Java – Paralelismus 52/ 55

Page 55: Semin r Java - Paralelismus

SynchronizedCollection

static class SynchronizedCollection<E> ... {

Collection<E> c; // Backing Collection

Object mutex; // Object on which to

// synchronize

SynchronizedCollection(Collection<E> c) {

this.c = c;

mutex = this;

}

SynchronizedCollection(Collection<E> c,

Object mutex)

{

this.c = c;

this.mutex = mutex;

}

Radek Kocı Seminar Java – Paralelismus 53/ 55

Page 56: Semin r Java - Paralelismus

SynchronizedCollection

public boolean add(E o) {

synchronized(mutex) {return c.add(o);}

}

public Iterator<E> iterator() {

return c.iterator();

// Must be manually synchronized by user!

}

Radek Kocı Seminar Java – Paralelismus 54/ 55

Page 57: Semin r Java - Paralelismus

Zdroje informacı

http://download.oracle.com/javase/

tutorial/essential/

http://www.javaworld.com

Radek Kocı Seminar Java – Paralelismus 55/ 55