3.Aloitusseminaarin kalvot - Noppa

P|||Q
812315A Ohjelmiston
rakentaminen.
Asynkronisuus
Ari Vesanen
ari.vesanen (at) oulu.fi
P|||Q
Yleistä moduulista


Tällä kertaa sisältää Java-kielistä monisäieohjelmointia
Suoritustapa: Neljästä ohjelmointitehtävästä valitaan
kaksi, joihin laaditaan ratkaisut
 Arvostellaan 1-5, loppuarvosana keskiarvo
mahdollisesti ylöspäin pyöristettynä
 Suositellaan tekemään Javalla, C++ mahdollinen,
muista kielistä sovittava erikseen
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
2
P|||Q
Moduulin aikataulu



Aloitusseminaari 16.6. klo 10-16
 Lyhyt johdanto rinnakkaisuuteen ja Java-kielen
monisäieohjelmointiin
 Rinnakkaisuuden piirteitä ja ohjelmointitehtäviä
 Suoritettavien tehtävien läpikäynti
17.6. – 4.8. Kiivasta ohjelmointia ja tehtävien palautus
viimeistään 4.8
 Jokainen palauttaa omat ratkaisut
Lopetusseminaari 5.8. klo 10 - 16
 Käydään läpi ratkaisut ja vertaillaan niitä toisiinsa
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
3
P|||Q
Moduulin sisältö
I. Johdanto rinnakkaisuuteen
II. Javan rinnakkaisuuden perustoteutus
III. Rinnakkaisen ohjelmoinnin malleja
IV. Eloisuusongelmista
V. Edistyneempi Javan rinnakkaisuus
VI. Tehtävät
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
4
P|||Q
Kirjallisuutta





Goetz, B. et al.:
 Java Concurrency in Practice, Addison-Wesley 2010
González, J.:
 Java 7 Concurrency Cookbook. Packt Publishing 2012.
Hartley, S.:
 Concurrent Programming, The Java Programming
Language, Oxford University Press Inc. 1998
Lea, D.:
 Concurrent Programming in Java, design Principles
and Patterns Second Edition, Addison-Wesley 2000
Kaksi viimeistä ennen Java 5.0:aa
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
5
P|||Q
WWW-lähteitä


Javan API-dokumentaatio:
 https://docs.oracle.com/javase/8/docs/api/
Oraclen Java-tutoriaali
 http://docs.oracle.com/javase/tutorial/essential/concurrency

Muita Java-tutoriaaleja
 http://www.tutorialspoint.com/java/java_multithreading.htm
 http://tutorials.jenkov.com/java-concurrency/index.html

Aalto-yliopiston kurssi
 https://noppa.aalto.fi/noppa/kurssi/t-106.5600/luennot
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
6
P|||Q
I Johdanto rinnakkaisuuteen
Peräkkäinen



Käskyt suoritetaan
peräkkäin
Yksikäsitteinen
suorituspolku
Deterministinen
 sama syöte,
sama tulos aina
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
vs.
Rinnakkainen



Toimintoja
suoritetaan
rinnakkain
Ei selvää
suorituspolkua
Epädeterministinen
 tulos voi riippua
suoritusjärjestyksestä
812315 Ohjelmiston rakentaminen, Asynkronisuus
7
P|||Q
I.1 Prosessit ja säikeet



Prosessi
 Tapa ajaa useita ohjelmia rinnakkain yhdessä
prosessorissa
 Oma muistialue
 Kommunikointi esim. putkilla tai socketeilla
Säie
 Prosessia kevyempi
 Prosessi voidaan jakaa säikeisiin
 Säikeellä oma ohjelmalaskuri ja pino
 Säikeet jakavat prosessin muistialueen ja resurssit
Tässä moduulissa monisäieohjelmointia
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
8
P|||Q
I.2 Rinnakkaisen ohjelman oikeellisuuskriteerit



Turvallisuus (safety)
 Oliot ja muuttujat pysyvät kunnossa
Eloisuus (liveness)
 Kaikki aiotut operaatiot suoritetaan joskus
Turvallisuus:
 Ei-atomaarinen operaatio voi epäonnistua jos kaksi
säiettä toimii yhtä aikaa -> Metodi voi toimia väärin
jos sitä kutsutaan kahdesta säikeestä

Säieturvallinen (thread safe): toimii oikein millä tahansa
kutsujärjestyksellä
 Resurssin käsitteleminen kahdesta säikeestä
samanaikaisesti = kilpailutilanne (race condition)
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
9
P|||Q
I.2 Rinnakkaisen ohjelman oikeellisuuskriteerit


Eloisuus:
 Aiotut operaatiot suoritetaan – ei aikarajaa
 Reaaliaikainen ohjelmointi – asetetaan aikarajoja
 Turvallisuus ja eloisuus jossain määrin vastakkaisia
Ongelmatilanteisiin varauduttava suunnitteluvaiheessa
 Ohjelman debuggaus erittäin vaikeaa (lokitiedoston
kirjoitus usein auttaa)
 Ohjelman täydellinen testaus mahdotonta
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
10
P|||Q
II Javan rinnakkaisuuden perustoteutus



Java alkujaan suunniteltu tukemaan rinnakkaisuutta
Olio-ohjelmoinnin ja Javan perusteet oletetaan
tunnetuksi
Javan virtuaalikone (JVM) suorittaa Java-ohjelman
 huolehtii myös rinnakkaisuudesta
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
11
P|||Q
II.1. Javan säikeet



Käyttäjäsäikeet (user threads)
 varsinaiset säikeet
Taustasäikeet (daemon threads)
 toimivat taustalla
Ohjelma loppuu, kun
 sen kaikki käyttäjäsäikeet päättyvät tai
 kutsutaan Runtime luokan exit()-metodia (koodissa
System.exit(0);)
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
12
P|||Q
II.1. Javan säikeet. Säikeen tilat






Uusi (NEW)
Säie on luotu, ei voi vielä toimia
Ajettava (RUNNABLE)
Säie voi toimia, kun saa suoritusaikaa
Estetty (BLOCKED)
Toiminta on estetty, koska odottaa lukon vapautumista
Odottaa (WAITING)
Säie odottaa toisen säikeen operaatiota
Odottaa ajastetusti (TIMED_WAITING)
Kuten yllä tai kun annettu aika on kulunut
Lopetettu, kuollut (TERMINATED)
Säikeen suoritus on loppunut
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
13
P|||Q
II.1. Javan säikeet. Säikeen luominen




1.
2.
3.
Kirjoita luokka, joka perii Thread-luokan
 run()-metodi uudelleenmääriteltävä
TAI
Kirjoita luokka joka toteuttaa Runnable –rajapinnan
 toteutettava run()-metodi
Säikeen suorittaminen:
Luo uusi Thread-olio
Konfiguroi (ei pakollinen)
 Anna prioriteetti ja nimi
Käynnistä kutsumalla start()-metodia
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
14
P|||Q
II.1. Javan säikeet. Säikeen luominen (2)



HUOM1: Käynnistys kutsumalla startia, toiminnallisuus
runissa!
HUOM2: Säie päättyy, kun run loppuu
Testaa ohjelmia
 Basicthreads.java
 BasicRunnable.java
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
15
P|||Q
II.1. Javan säikeet. Säikeen lopettaminen



Säie päättyy kun run loppuu
Suositeltavin tapa säikeen keskeyttämiseen: interrupt
 asettaa säikeen keskeytystilaan, ei lopeta suoritusta
 tutki onko keskeytetty (metodi isInterrupted())
 myös interrupted() - nollaa keskytystilan
Nukkuvan tai odottavan säikeen keskeyttäminen
aiheuttaa poikkeuksen InterruptedException
 säie ei ajossa -> ei voi suoraan keskeyttää
 ko. poikkeus on aina käsiteltävä kun tehdään wait tai
sleep
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
16
P|||Q
II.1. Javan säikeet. Säikeen lopettaminen
//Määritellään säieluokka
class Interruptible extends Thread{
public void run(){
while(!this.isInterrupted()){ // Tee jotain}
// Lopputoimenpiteet
}
}
//Pääohjelmassa koodi:
Interruptible irThread = new Interruptible();
irThread.start();
// Toimenpiteitä pääohjelmassa
// Lopetetaan irThread
irThread.interrupt();

Tehtävä ThreadInterrupt.java
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
17
P|||Q
II.2. Javan säikeiden synkronointi

1.
2.

Oikean toiminnan varmistamiseksi kahdenlaista
synkronointia
Kilpailun synkronointi
 Tarvitaan kun resurssia käytetään monesta säikeestä
Yhteistoiminnan synkronointi
 Tarvitaan kun säikeen toiminta riippuu toisen säikeen
toiminnasta
Javan perusmekanismi monitori = olio, jolla on lukko ja
odotusjoukko
 Mikä tahansa Javan olio voi olla monitori
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
18
P|||Q
II.2.1 Javan monitorin toiminta
SP. JOUKKO
SÄIE 5
SÄIE 6
Odotusjoukko (wait
set) = ne säikeet
jotka odottavat
ilmoitusta (notify())
kutsuttuaan wait() –
metodia
METODI1
SÄIE 1
METODI2 Sisäänpääsyjoukko
LOHKO1
SÄIE 3
SÄIE 2
SÄIE 4
(entry set) =
säikeet, jotka
odottavat pääsyä
monitoriin
ensimmäistä kertaa
ODOTUSJOUKKO
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
19
P|||Q
II.2.2 Kilpailun synkronointi



Lukko otetaan haltuun kutsumalla synchronizedavainsanalla merkittyä metodia (tai koodilohkoa)
 olion kaikkien synkronoitujen metodien ja lohkojen
suorittaminen estyy kunnes säie luopuu lukosta
Lukosta luopuminen:
 Synkronoitu metodi/lohko loppuu
 Säie siirtyy odotustilaan
HUOM! Thread.sleep(); ei aiheuta lukosta luopumista.
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
20
P|||Q
II.2.2 Kilpailun synkronointi (2)
ESIM: Seuraavat yhtäpitävät:
synchronized void f(){
// Metodin runko
}

void f(){
synchronized(this){
// Metodin runko
}
}
 Tehtävä: Poista kilpailutilanne ohjelmista
RaceCondition.java ja UnsafeTicketOffice.java
 Optimoi synkronointi jälkimmäisessä
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
21
P|||Q
II.2.3 Yhteistoiminnan synkronointi




Säikeessä voidaan odottaa toisen säikeen päättymistä
kutsumalla sen join()-metodia
Monitorin odotusjoukkoon voidaan vaikuttaa metodeilla
 wait(): asettaa kutsuvan säikeen odotustilaan
 notify(): vapauttaa yhden odottavan säikeen
 notifyAll(): vapauttaa kaikki odottavat säikeet
Kaikkien em. metodien kutsumiseksi on oltava hallussa
monitorin lukko
Vapautetut säikeet kilpailevat normaaliin tapaan
monitorin lukosta
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
22
P|||Q
II.2.3 Yhteistoiminnan synkronointi (2)


Jos odottava säie keskeytetään, syntyy
InterruptedException
 Käsiteltävä, jos kutsutaan wait()-metodia
Tehtävä: Ohjelmassa PingPongEx.java kaksi säiettä
kutsuu luokan PingPongController metodeja, jotka
tulostavat sanat ”PING” ja ”PONG”
 Synkronoi luokka PingPongController niin, että sanat
tulostetaan aina vuorotellen. Metodeissa esiintyviä
sleep-aikoja ei saa muuttaa
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
23
P|||Q
III Rinnakkaisen ohjelmoinnin malleja
III.1 Tuottaja-kuluttajamalli





Soveltuu moneen rinnakkaisen ohjelmoinnin ongelmaan
Kahdentyyppisiä säikeitä (tai prosesseja):
Tuottajat
 Luovat uusia olioita (dataa)
Kuluttaja
 Käsittelevät tuottajien luomia olioita
Olioiden varastona voidaan käyttää esim. synkronoitua
syklistä puskuria:
 Huolehdittava, että vain yksi säie käsittelee puskuria
 Huolehdittava että täyteen puskuriin ei kirjoiteta
 Huolehdittava että tyhjästä puskurista ei lueta
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
24
P|||Q
III.2 Lukija-kirjoittajamalli




Alunperin mallinsi tietokannan toimintaa
Yleishyödyllinen rinnakkaisessa ohjelmoinnissa
 Voidaan käyttää säätelemään pääsyä monenlaisiin
resursseihin
Kahdenlaisia säikeitä: lukijasäikeet ja kirjoittajasäikeet
 resurssia saa lukea moni säie yhtä aikaa
 resurssia voi päivittää vain yksi (kirjoittaja)säie
 resurssia ei saa lukea jos kirjoitetaan
Abstrakti luokka ReadAndWRite mallintaa toimintaa,
operaatiot readOperation() ja writeOperation()
määriteltävä perivässä luokassa
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
25
P|||Q
IV Eloisuusongelmat



Lukkiutuminen (deadlock)
 Yleinen syy säikeiden jumittumiseen
 Säikeet odottavat ristiin toistensa lukitsemien
resurssien vapautumista
Uloslukkiutuminen
 Koodi voi sisältää sisäkkäisiä olioita joilla
synkronoituja metodeja -> Säie voi lukita itsensä ulos
Menetetty signaali
 Säie odottaa signaalia, joka on tuotettu ennen kuin
säie alkoi odottaa
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
26
P|||Q
V Javan edistyneempi rinnakkaisuuden hallinta


Javan versioon 5.0 lisätukea rinnakkaisuuden hallintaan
 java.util.concurrent
 java.util.concurrent.locks
 java.util.concurrent.atomic
Em. Pakkaukset sisältävät
 Erilaisia synkronointiprimitiivejä,
 Rinnakkaisessa ohjelmoinnissa käyttökelpoisia
kokoelmia,
 Säieturvallisia muuttujatyyppejä
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
27
P|||Q
V.1 Semaforit




Semafori: kokonaislukumuuttuja, jonka arvo on lupien
lukumäärä
Säie pyytää lupaa semaforilta:
 Jos arvo suurempi kuin nolla, säie saa luvan ja arvoa
vähennetään
 Jos arvo nolla, säie jää odottamaan, kunnes lupien
määrä kasvaa
Kun säie luopuu luvasta, semaforin arvoa kasvatetaan
Voidaan käyttää poissulkevuuteen tai synkronoituna
laskurina
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
28
P|||Q
V.1 Semaforit (2)
Javassa semafori luokka Semaphore, pakkauksessa
java.util.concurrent
 Käyttö:
// Luodaan semafori, jolla alussa yksi lupa
Semaphore sema = new Semaphore(1);
// Luvan pyytäminen
sema.acquire();
// Luvan vapauttaminen
sema.release();

Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
29
P|||Q
V.2 Lukot ja ehtomuuttujat
Pakkauksessa java.util.concurrent.locks rajapinta Lock
 Erilaisia implementointeja -> perussynkronointia
monipuolisempi toteutus
 Lukkoihin voidaan liittää Condition-rajapinnan
toteuttavia olioita vastaamaan ehtomuuttujia
 Käyttöidiomi kilpailun synkronoinnille
Lock lukko = ...; // Sopiva lukko-olio
lukko.lock();
try { // Käytä lukon suojaamaa resurssia
}
finally {
lukko.unlock(); // Varma vapauttaminen
}

Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
30
P|||Q
V.2 Lukot ja ehtomuuttujat (2)

Luokan ReentrantLock olio Javan monitorin yleistys
 Olioon voi liittyä useita ehtomuuttujia (Condition),
luodaan luokan metodilla newCondition()
 Condition-olion odotusmetodi await() ja
ilmoitusmetodit signal() sekä signalAll()



Vastaavat Object-luokan metodeja wait(), notify() sekä
notifyAll()
Katso esimerkkiohjelmista CircularBufferWithLocks.java
Tehtäviä: Poista ohjelmista RaceConditionRunnable.java
ja UnsafeTicketOffice.java kilpailutilanne lukkoja
käyttämällä. Muuta aiemmin tehty PingPong-ohjelma
käyttämään lukkoja.
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
31
P|||Q
V.3 Suorittajat ja säievarastot
Javan pakkaukseen java.util.concurrent sisältyy rajapinta
Executor, jonka avulla voidaan eristää tehtävän välitys ja
sen suoritusmekanismi toisistaan.
 Metodi void execute(Runnable r)
 Toteuttamalla rajapinta saadaan erilaisia suorittajia
 Luokissa voidaan käyttää Executor-oliota ja sitoa se
vasta myöhemmin tietyntyyppiseen suorittajaan, esim
class SimpleExecutor implements Executor{
public void execute(Runnable r){
new Thread(r).start();
}
}

Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
32
P|||Q
V.3.1 Säievarastot


Kiinteä määrä säikeitä, joille annetaan tehtäviä
suoritettavaksi
 Vähentää tarvittavien säikeiden määrää, jos tehtävien
ei tarvitse olla yhtä aikaa ajossa
Javan luokka ThreadPoolExecutor
 Olio saadaan kutsumalla Executors-luokan staattista
metodia newFixedThreadPool(int poolSize)
 Tehtävä käynnistetään luokan metodilla execute ->
pääsee suoritukseen kun varaston säie vapautuu
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
33
P|||Q
V.3.1 Säievarastot (2)



Javan luokka ThreadPoolExecutor jatkuu
 Luokan metodi shutdown() -> tehtävät ajetaan
loppuun, uusia ei oteta
 Luokan metodi awaitForTermination() odottaa kunnes
kaikki tehtävät suoritettu
Ks. esimerkit NQueensWithPool.java ja
NQueensWithPoolLatch.java
Tehtävä: Jälkimmäisessä CountDownLatch odottaa
tehtävien valmistumista. Korvaa se semaforilla.
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
34
P|||Q
VI Tehtävät


1.
2.
3.
4.
Jokainen palauttaa oman ratkaisun
Seuraavista neljästä tehtävästä valitaan kaksi
 Kuvaukset erillisessä dokumentissä
Boolimaljasimulaatio
Kanjonia ylittävät turistit
Huvipuiston vuoristorata
Neljä samaa numeroa -peli
Ari Vesanen, Tietojenkäsitttelytieteiden laitos
812315 Ohjelmiston rakentaminen, Asynkronisuus
35