Helsingin yliopisto > Tietojenkäsittelytieteen laitos > Ohjelmointitekniikka (Java) -opintojakso keväällä 2005

Koetehtävän 4 arvostelukertomus

Tehtävä

Seuraava ohjelmahahmo ("idiomi") on tyypillinen:
  void run () {
    try { 
      while (! interrupted () && hasMoreWork) 
        ... // may block and throw..
    }
    catch (InterruptedException e) ...
      // interrupted during sleep or wait 
      ...
    finally 
      ... // cleanup in any case
  }
Selitä mistä on kysymys ja miksi keskeyttämistä on syytä tutkia kahdella erilaisella tavalla.

Esimerkkivastaus

Kyseessä on Thread-luokasta periytetyn luokan run-metodi. Metodi jakaantuu kolmeen osaan. Ensimmäisessä osassa on while-silmukka try-lohkon sisällä. Silmukka pyörii niin kauan kuin hasMoreWork() metodi palauttaa arvon true tai kunnes Thread-luokasta peritty interrupted-metodi palauttaa arvon true joka tarkoittaa sitä, että jokin ohjelman osa on pyytänyt säiettä keskeyttämään toimintansa säikeeen interrupt-metodia kutsumalla. Kommentissa myös mainitaan, että while-silmukan sisällä koodin suoritus voi pysähtyä ja että koodi voi heittää poikkeuksen.

Toisessa osassa catch-lohko nappaa while-silmukkaa suorittaessa mahdollisesti syntyneen InterruptedException-poikkeuksen jonka joku ohjelman osa on aiheuttanut interrupt-metodia kutsumalla ja käsittelee sen jotenkin.

Kolmannessa osassa finally-lohkossa suoritetaan loppusiivous riippumatta siitä heitettiinkö poikkeusta vai ei.

Tämä ohjelmahahmo on Javassa varsin tyypillinen tapa ajaa jotain osaa koodista omassa säikeessään rinnakkain ohjelman muiden osien kanssa. Säikeen toiminnan keskeyttämistä on syytä tutkia kahdella tavalla sen vuoksi, että jokin muu ohjelman osa voi pyytää keskeytystä joko silloin kun try-lohkossa oleva silmukka on parhaillaan aktiivisesti tekemässä jotain tai silloin kun silmukka on seisahtuneena esimerkiksi sleep-metodin kutsumisen vuoksi.

Jos keskeytystä pyydetään silloin kun silmukka on seisahtuneena sleep-metodin tai vastaavan kutsumisen vuoksi tai sitä on pyydetty jossain aikaisemmassa vaiheessa keskeytys aiheuttaa InterruptedException-poikkeuksen heittämisen. Jos sen sijaan keskeytystä pyydetään kesken suorituksen eikä silmukka kutsu sleep-metodia tai vastaavaa poikkeusta ei heitetä vaan silmukan on itse tarkistettava mahdollinen keskeytys interrupted-metodia kutsumalla.

Syy tähän järjestelyyn on yksinkertainen. Jos while-silmukka on parhaillaan tekemässä jotain niin poikkeuksen heittäminen mielivaltaisessa kohdassa tekisi ohjelman logiikan eheyden säilyttämisen vaikeaksi joten silmukan on annettava itse tutkia tilaansa kohdassa jossa se pystyy vaaratta keskeyttämään toimintansa. Toisaalta ollessaan pysähtyneenä silmukka ei itse voi tutkia tilaansa joten tarvitaan myös poikkeusta.

Pisteytys

Vastauksesta sai enintään 6 pistettä.

Eri kohdista sai pisteitä seuraavasti:

1 piste: Selitetty miten ohjelmahahmo liittyy rinnakkaisuuden toteuttamiseen Javalla.

1 piste: Selitetty InterruptedException-poikkeuksen heittäminen ja sen kiinniotto catch-lohkossa.

1 piste: Selitetty interrupted-metodin käyttötarkoitus ja käyttö.

1 piste: Selitetty miksi InterruptedException-poikkeuksen heittäminen ja sen kiinniotto catch-lohkossa ei yksin riitä.

1 piste: Selitetty miksi interrupted-metodin käyttö ei yksin riitä.

1 piste: Selitetty finally-lohkon käyttötarkoitus ja käyttö.

Jokaisesta näistä kohdista saadut pisteet jätettiin antamatta kokonaan tai osittain jos vastaus oli puutteellinen, virheellinen tai epäselvä.

Melko yleinen virhe tässä tehtävässä oli sekoittaa notify- ja interrupt-metodien käyttötarkoitus. Huomaa, että notify- ja notifyAll-metodeilla herätetään wait-tilassa odottajia mikä on eri asia kuin säikeen toiminnan keskeyttäminen interrupt-metodilla.

Pyöristykset tehtiin ylöspäin.

Pisteiden jakauma

Yhteispisteiden keskiarvoksi muodostui 2,6.

Taulukko 1. Pisteiden jakauma
yhteispisteet vastausten lukumäärä
6 2
5 5
4 9
3 14
2 13
1 11
0 4