Luento 6. T Ohjelmoinnin jatkokurssi T1 & T Ohjelmoinnin jatkokurssi L1. Luennoitsija: Otto Seppälä

Samankaltaiset tiedostot
Ohjelmoinnin peruskurssien laaja oppimäärä

Projekti 1 Säikeet ja kriittisen vaiheen kontrollointi javalla

Rinnakkaisohjelmointi kurssi. Opintopiiri työskentelyn raportti

JAVA-OHJELMOINTI 3 op A274615

Liite 1. Projektin tulokset (Semaforit Javassa) Jukka Hyvärinen Aleksanteri Aaltonen

Monitorit -projekti Rinnakkaisohjelmointi

Ohjelmoinnin peruskurssien laaja oppimäärä

Java ja grafiikka. Ville Sundberg

HOJ Säikeet (Java) Ville Leppänen. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.1/55

JAVA on ohjelmointikieli, mikä on kieliopiltaan hyvin samankaltainen, jopa identtinen mm. C++

Luokat ja oliot. Ville Sundberg

Sovelmat. Janne Käki

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Ohjelmoinnin peruskurssien laaja oppimäärä

Mikä yhteyssuhde on?

Rinnakkaisohjelmointi, Syksy 2006

1 Tehtävän kuvaus ja analysointi

Ohjelmoinnin jatkokurssi, kurssikoe

Javan perusteita. Janne Käki

9. Periytyminen Javassa 9.1

Javan semaforit. Joel Rybicki, Aleksi Nur mi, Jara Uitto. Helsingin yliopisto

Olio-ohjelmointi Javalla

Listarakenne (ArrayList-luokka)

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Metodien tekeminen Javalla

Rajapinta (interface)

5. HelloWorld-ohjelma 5.1

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä

Tehtävä 1. Tehtävä 2. Arvosteluperusteet Koherentti selitys Koherentti esimerkki

Ohjelmointi 2 / 2010 Välikoe / 26.3

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Olio-ohjelmointi Käyttöliittymä

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

8. Näppäimistöltä lukeminen 8.1

Graafisen käyttöliittymän ohjelmointi Syksy 2013

1. Omat operaatiot 1.1

Sisältö Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 26.2

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Pakkaukset ja määreet

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

812315A Ohjelmiston rakentaminen. Asynkronisuus

8. Näppäimistöltä lukeminen 8.1

T Henkilökohtainen harjoitus: FASTAXON

12. Näppäimistöltä lukeminen 12.1

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

Ohjelmointi 1 / 2009 syksy Tentti / 18.12

11. Javan toistorakenteet 11.1

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

1. Mitä tehdään ensiksi?

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

11/20: Konepelti auki

16. Javan omat luokat 16.1

Sisällys. 6. Metodit. Oliot viestivät metodeja kutsuen. Oliot viestivät metodeja kutsuen

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Poikkeukset ja tietovirrat: Virhetilanteiden ja syötevirtojen käsittely

Tietorakenteet, laskuharjoitus 7,

10 Lock Lock-lause

Jaana Diakite Projekti 1 JAVA-Monitorit 1(13) Rinnakkaisohjelmointi Anu Uusitalo

9. Periytyminen Javassa 9.1

Hajautettujen sovellusten muodostamistekniikat (Java-kielellä), TKO_2014 Aineopinnot, syksy 2009 Turun yliopisto / Tietotekniikka

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2

Vertailulauseet. Ehtolausekkeet. Vertailulauseet. Vertailulauseet. if-lauseke. if-lauseke. Javan perusteet 2004

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

public static void main (String [] args)

Sisällys. Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2

12. Javan toistorakenteet 12.1

Luokan sisällä on lista

Java kahdessa tunnissa. Jyry Suvilehto

12. Javan toistorakenteet 12.1

Sisältö. 22. Taulukot. Yleistä. Yleistä

Ohjelmoinnin perusteet, kurssikoe

ITKP102 Ohjelmointi 1 (6 op)

7. Näytölle tulostaminen 7.1

815338A Ohjelmointikielten periaatteet

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

Ohjelmoinnin perusteet Y Python

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 16.3

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Sisältö. Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

Sisällys. JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta. Abstraktin luokan idea. Abstrakti luokka ja metodi. Esimerkki

14. Poikkeukset 14.1

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 15.3

Sisällys. JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys. Luokkahierarkia. Periytyminen (inheritance)

Sisällys. 15. Lohkot. Lohkot. Lohkot

Ohjelmointi 2 / 2011 Välikoe / 25.3

Ohjelmointi 2 / 2008 Välikoe / Pöytätestaa seuraava ohjelma.

Metodit Arvotyyppi. Metodit Arvotyyppi. Metodit Parametrit. Metodit Parametrit. Metodit Kuormittaminen. Metodit Kuormittaminen. Javan perusteet

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

4. Luokan testaus ja käyttö olion kautta 4.1

20. Javan omat luokat 20.1

Pakkauksen kokoaminen

Sisällys. 20. Javan omat luokat. Java API. Pakkaukset. java\lang

Javan GUI Scratchaajalle

Interaktiivinen tarinankerronta

Javan GUI Scratchaajalle

A) on käytännöllinen ohjelmointitekniikka. = laajennetaan aikaisemmin tehtyjä luokkia (uudelleenkäytettävyys)

Transkriptio:

Luento 6 T-106.1240 Ohjelmoinnin jatkokurssi T1 & T-106.1243 Ohjelmoinnin jatkokurssi L1 Luennoitsija: Otto Seppälä Kurssin WWW: http://www.cs.hut.fi/opinnot/t-106.1240/s2007

Oma Grafiikka Swing-käyttöliittymässä

Grafiikkaa Swingillä Oman grafiikan piirtäminen Swing-käyttöliittymässä on varsin helppoa. Periytä uusi luokka JPanel-luokasta Korvaa paintcomponent(graphics g)-metodi Graphics-luokan API-dokumentaatiosta selviää mitä kaikkea sillä voi tehdä piirtää ympyröitä, suorakulmioita, viivoja, tekstiä jne... Swing komponenttien paintcomponent-metodin parametri on yleensä Graphics2D-tyyppinen tyyppipakotuksen jälkeen voit piirtää myös bezier-käyriä, jne... Seuraavassa yksinkertainen esimerkki...

import java.awt.color; import java.awt.dimension; import java.awt.graphics; import javax.swing.jpanel; public class Ympyra extends JPanel { // piirretään Graphics-olion kautta ruudulle // punainen ympyrä ja tekstiä public void paintcomponent ( Graphics g ) { g.setcolor( Color.RED ); g.drawstring( "Maailman hienoin ympyrä!", 10, 10 ); g.drawoval(20,30,100,100); // pyydetään vähän enemmän tilaa ettei pack // paina komponenttia kasaan. public Dimension getpreferredsize() { return new Dimension(200,200);

import javax.swing.jframe; public class PaaIkkuna extends JFrame { public static void main( String[] args ) { PaaIkkuna ikkuna = new PaaIkkuna(); ikkuna.setvisible(true); ikkuna.pack(); public PaaIkkuna() { super("maailman hienoin ikkuna"); //Ikkunan sulkeminen lopettaa koko ohjelman this.setdefaultcloseoperation(jframe.exit_on_close); Ympyra ympyra = new Ympyra(); add(ympyra);

Säikeet ja Rinnakkaisohjelmointi

Rinnakkaisohjelmointi Sisältö Mikä on säie? Javan luokka Thread Luokan ominaisuudet Säikeen luonti ja käynnistäminen Perimällä luokka Thread Täyttämällä rajapinta Runnable Säikeiden synkronointi Monitori synchronized-määre ja synkronoidut lohkot wait() - notify() / notifyall() Muuta volatile-määre

Mikä on Säie? Prosessi Kaikissa nykyaikaisissa käyttöjärjestelmissä on mahdollista suorittaa useita ohjelmia yhtä aikaa Käyttöjärjestelmä ajaa jokaista ohjelmaa omassa prosessissaan, jakaen prosessoriaikaa ohjelmille niin, että ohjelmat näyttävät toimivan samanaikaisesti Säie Yhden prosessin sisällä myös yksittäinen ohjelma voi suorittaa eri toimintoja samanaikaisesti käyttämällä säikeitä (thread) Säikeet ovat prosesseihin verrattuna selkeästi kevyempiä

Mikä on säie? Sopivasti käytettynä säikeillä saadaan paljon etuja ohjelma voi käyttää prosessoriaikaa mahdollisimman tehokkaasti hyväkseen ohjelma voi vastata käyttäjän toimiin nopeammin jne. Jokaisella säikeellä on oma suorituspino paikallisia muuttujia (suorituspinossa) ei jaeta kaikki muu on yhteistä (keossa) Java tukee rinnakkaisohjelmointia jo kielen tasolla Selkiyttää asioita Monessa ohjelmointikielessä tuki säikeille toteutetaan jonkin ohjelmointikirjaston avulla

Luokka Thread Luokka Thread mahdollistaa säikeiden ohjaamisen sleep() pysäyttää säikeen halutuksi ajaksi interrupt() keskeyttää odotuksen start() käynnistää säikeen isalive() kertoo onko säie elossa join() odottaa säikeen kuolemista yield() antaa suoritusvuoron muille getname() kertoo säikeen nimen getpriority() kertoo säikeen prioriteetin setpriority() asettaa säikeen prioriteetin currentthread() antaa ajossaolevan säikeen

Luokka Thread Luokassa on myös vanhentuneita metodeja joiden käyttöä tulisi välttää. suspend() resume() stop()

Sleep Allaoleva ohjelma tulostaa sanan Testi kolme kertaa noin kolmen sekunnin välein public class Esimerkki { public static void main ( String[] args) { Thread tamasaie = Thread.currentThread(); try { for (int i=0; i<3; i++) { System.out.println( Testi ); tamasaie.sleep(3000); catch (InterruptedException e) {

Sleep Sleepin parametri kertoo kuinka kauan säie on pysähdyksissä (millisekunneissa) HUOM! Tämä on minimiaika. Säikeen paluu ajoon voi kestää pidempään. (Älä rakenna kelloa sleep-metodilla) Mitä muuta esimerkissä tapahtui? Viittaus ajettavan säikeen Thread-olioon haettiin Thread luokan luokkametodilla currentthread() Sleep-metodin kutsu oli sijoitettu try-catch rakenteen sisään, koska säikeen nukkuminen voidaan keskeyttää kutsumalla sen interruptmetodia

Säikeen luonti ja käynnistys Kuinka säie luodaan? Uusi säie voidaan luodaan luomalla uusi Thread-olio ja kutsumalla sen start-metodia Start käynnistää säikeen halutusta aloituskohdasta Ennen start()-metodin kutsua säie on pysähdyksissä Tämä aloituspiste voidaan antaa kahdella tavalla toteuttamalla rajapinta Runnable periyttämällä uusi luokka luokasta Thread Lopputulos on molemmissa tapauksissa sama suoritus alkaa jommankumman metodista run() run()-metodia ei kutsuta suoraan vaan Thread tekee sen kun sitä vastaava säie käynnistetään start:illa säikeen suoritus päättyy kun run()-metodista poistutaan

Rajapinta Runnable Runnable-rajapinta määrittää edellämainitun metodin public abstract void run() Runnable-olio annetaan Thread-luokan konstruktorille parametrina Thread saie = new Thread( runnableolio); Alussa säie on pysähdyksissä, mutta kun sen start()- metodia kutsustaan, säie käynnistyy ja aloittaa suorituksensa Runnable-olion run()-metodista saie.start( );

Runnable rajapinta public class Tulostaja implements Runnable { private String viesti; public Tulostaja( String tulostatama ) { this.viesti = tulostatama public void run () { Thread tamasaie = Thread.currentThread(); try { for (int i=0; i<10; i++) { tamasaie.sleep(500); System.out.println( Viesti + i); catch (InterruptedException e) {

Runnable rajapinta public class Esimerkki2 { public static void main ( String[] args){ Tulostaja t = new Tulostaja( Moi : ); Tulostaja u = new Tulostaja( Hei : ); Thread saiea = new Thread(t); Thread saieb = new Thread(u); saiea.start(); saieb.start(); try { for (int i=0; i<10; i++) { thread.currentthread().sleep(1000); System.out.println( Main + i); catch (InterruptedException e) {

Thread-luokan periminen Aloituspiste voidaan antaa myös perimällä luokka Thread ja korvaamalla sen metodi run() public void run() Kun Thread-olio luodaan konstruktorilla joka ei ota viitettä Runnable-olioon, start()-metodin kutsu kutsuu Thread-olion omaa run()-metodia Käytännössä siis Thread-olio on itse tuolloin oma Runnable()- olionsa Runnable-rajapinnan täyttäminen on monesti selkeämpi vaihtoehto.

Muutama muu metodi isalive() tiedustelee, onko tutkittu säie elossa join() odottaa kunnes säie, jonka join-metodia kutsuttiin kuolee Voidaan vaikkapa odottaa, että jonkin olennaisen tehtävän suoritus saadaan loppuun Voi olla kätevä ohjelman alasajossa Huomaa, että join() ei lopeta säikeitä vaan odottaa että ne kuolevat luonnollisesti yield() Tällä-hetkellä ajossa oleva säie luovuttaa ajovuoronsa muille

Säikeiden synkronointi

Synkronointi Kun kaksi säiettä tai useampi säie haluaa käyttää jotakin yhteistä resurssia (muuttuja, tiedosto, jne) yhtäaikaisesti, täytyy pitää huolta että vain yksi säie kerrallaan käsittelee resurssia. Esim tilanne jossa kaksi säiettä avaavat saman tiedoston ja kirjoittavat siihen. Menevätkö kirjoitetut rivit sekaisin? Toimintaa, joka takaa tämän yksi kerrallaan - periaatteen kutsutaan synkronoinniksi

Monitori Javassa synkronointi toteutetaan ns. monitorin avulla Monitori on jokin alue ohjelmakoodista, joka suojataan lukkoolion avulla - Mikä tahansa Java:n olio voi toimia lukkona Vain yksi säie kerrallaan voi olla ajossa monitorin sisällä jos jokin säie on jo ajossa monitorin sisällä, muut säikeet odottavat ulkopuolella kunnes sisällä oleva säie poistuu monitorista säie voi poistua monitorista joko niin, että se poistuu koodialueelta normaalisti tai siirtymällä odottamaan kutsumalla metodia wait() Monitorin alue rajataan synchronized-määreen avulla

Synchronized Synchronized-määreellä on kaksi käyttötapaa Määre voidaan kirjoittaa metodin eteen, jolloin se olio, jonka metodia kutsutaan toimii monitorin lukkona public class Posti { public synchronized Paketti otapaketti() { // jotain koodia public synchronized void tuopaketti( Paketti paketti ){ // jotain koodia Annetussa esimerkissä Posti-olio toimii itse lukkona, siten, että vain yksi säie kerrallaan voi suorittaa jotakin luokasta löytyvää synkronoitua metodia. paketteja ei siis voi tuoda samanaikaisesti, viedä samanaikaisesti taikka tuoda ja viedä yhtä aikaa, jolloin kukaan ei mm. voi viedä samaa pakettia kahdesti

Synchronized Toinen käyttötapa synchronized määreelle on kirjoittaa synkronoitu lohko, jonka yhteydessä määritetään olio, joka toimii lukkona public class Posti { ArrayList lahtevatpaketit; public Paketti otapaketti() { // jotain koodia synchronized( lahtevatpaketit ) { // koodia joka käsittelee pakettien jonoa // jotain koodia Tässä lahtevatpaketit on lukko, joka estää että synkronoituun lohkoon pääsisi useampi säie kerrallaan

wait() ja notify() Entäs jos postissa ei olekaan paketteja? Tietenkin voitaisiin kirjoittaa silmukka joka käy hakemassapakettia kunnes saa sellaisen Käytännössä tämä veisi kaikki järjestelmän suoritustehot turhan silmukan suoritukseen Ongelma ratkeaa metodeilla wait() ja notify() Kutsumalla lukko-olion metodia wait() säie poistuu monitorista ja siirtyy odottamaan Kun joku toinen säie kutsuu lukko-olion metodia notify(), se herättää yhden wait-jonon säikeen odottamaan pääsyä takaisin suoritukseen wait-kutsua seuraavalta riviltä Kaikki wait-jonon säikeet voi siirtää ready-jonoon komennolla notifyall()

public class Posti { private ArrayList<Paketti> paketit = new ArrayList<Paketti>(); public static final int POSTIN_KOKO = 15; public synchronized Paketti otapaketti() { while( paketit.isempty() ) { wait(); Paketti poistettava = paketit.remove(0); notify(); return poistettava; public synchronized void tuopaketti( Paketti p ) { while( paketit.size() >= POSTIN_KOKO ) { wait(); paketit.add( p ); notify();

Javan monitori ajovalmiit säikeet Edellinen säie poistuu monitorista Monitori synkronoitu metodi monitorissa oleva säie siirtää yhden säikeen ajovalmiuteen kutsumalla notify() notify Monitorissa juuri nyt oleva säie synkronoitu metodi odottavat säikeet wait synkronoitu metodi Monitorissa oleva säie siirtää itsensä odottamaan kutsumalla wait()

Volatile Säikeet voivat tehokkuussyistä käyttää väliaikaisesti omia kopioita joistakin yhteisistä muuttujista Mikäli on erityisen tärkeää että jonkin muuttujan tila on yksikäsitteinen, kirjoitetaan muuttujan määrittelyyn sana volatile Tämä pakottaa javan käyttämään vain yhtä kopiota muuttujasta Samaan päästään luonnollisesti myös sopivalla synkronoinnilla Huom: volatile ei ole tapa toteuttaa synkronointia

Säikeet ja GUI Viime luennolla katsottiin kuinka graafinen käyttöliittymä toteutetaan Javalla Luodaan jokin päätason säiliö Luodaan muista säiliöitä ja nappuloita jne Valitaan säiliöille sopivat layout managerit Lisätään nappulat ja säiliöt päätason säiliöön Lisätään nappuloihin jne. tapahtumankuuntelijat Laitetaan päätason säiliö näkyviin

Säikeet ja GUI Tämä toimii hyvin kun tapahtumankuuntelijan tekemä työ on tehtävissä nopeasti. Entä jos nappulan painaminen aloittaa animaation tai raskaan laskutoimituksen? Käyttöliittymä pysähtyy siksi aikaa kun tapahtumankuuntelijan metodi suorittaa jotakin tehtävää. Näyttöäkään ei ehkä päivitetä. Tämän saa ratkaistua käyttämällä säikeitä. Tutustu luentoesimerkkiin www-sivuilla