Yksi monimutkaisen järjestelmän suurimmista haasteista on pystyä reagoimaan tehtävien toteutuksen aikana. Tämä haaste on vielä suurempi laajennettavassa järjestelmässä, jossa samoja resursseja käyttävät sellaiset komponentit, joita ei ole alun perin suunniteltu ajettaviksi yhdessä. org.eclipse.core.runtime.jobs-paketti ratkaisee ongelman tuomalla käyttöön rakenteen, jonka avulla voi ajoittaa, toteuttaa ja hallita samaan aikaan ajossa olevia toimintoja. Tämä rakenne perustuu töiden käyttöön sellaisten työn yksikköjen kuvaamiseksi, jotka voi ajaa asynkronisesti.
class TrivialJob extends Job { public TrivialJob() { super("Trivial Job"); } public IStatus run(IProgressMonitor monitor) { System.out.println("This is a job"); return Status.OK_STATUS; } }Seuraava katkelma luo ja ajoittaa työn:
TrivialJob job = new TrivialJob(); System.out.println("About to schedule a job"); job.schedule(); System.out.println("Finished scheduling a job");Tämän ohjelman tuloste määräytyy ajoituksen mukaan. Toisin sanoen ei ole mitään keinoa olla varma siitä, milloin työn run-metodi ajetaan suhteessa säikeeseen, joka loi työn ja ajoitti sen. Tuloste on joko
About to schedule a job This is a job Finished scheduling a jobtai
About to schedule a job Finished scheduling a job This is a job
Jos haluat varmistua, että työ on valmis, ennen kuin jatkat, voit käyttää join()-metodia. Tämä metodi estää kutsujaa, kunnes työ on valmis tai kutsuva säie on keskeytetty. Seuraavaksi kirjoitetaan aiempi katkelma uudelleen:
TrivialJob job = new TrivialJob(); System.out.println("About to schedule a job"); job.schedule(); job.join(); if (job.getResult().isOk()) System.out.println("Job completed with success"); else System.out.println("Job did not complete successfully");Jos oletetaan, että join()-kutsu ei keskeydy, tämä metodi palauttaa varmasti seuraavan tuloksen:
About to schedule a job This is a job Job completed with success
Yleensä ei tietenkään ole hyödyllistä liittää työtä heti sen ajoituksen jälkeen, koska silloin ei saavuteta samanaikaisuutta. Tässä tapauksessa työn voisi yhtä hyvin tehdä työn run-metodista suoraan kutsuvassa säikeessä. Myöhemmin tarkastellaan muita esimerkkejä, joissa liittämisestä on enemmän hyötyä.
Edellisessä katkelmassa käytetään myös työn tulosta. Tulos on IStatus-objekti, joka palautuu työn run()-metodista. Tämän tuloksen avulla voit välittää tarvittavat objektit takaisin työn run-metodista. Tuloksen avulla voi osoittaa myös epäonnistumisen (palauttamalla IStatus-arvon, jonka vakavuus on IStatus.ERROR) tai peruutuksen (IStatus.CANCEL).
Aiemmin on tarkasteltu työn ajoitusta ja sen valmistumisen odotusta, mutta töiden avulla voi tehdä muutakin hyödyllistä. Jos ajoitat työn, mutta päätät sitten, ettei sitä tarvita, työn voi lopettaa cancel()-metodin avulla. Jos työn ajo ei peruutushetkellä ole vielä alkanut, työ hylätään heti eikä sitä ajeta. Jos työn ajo sen sijaan on jo alkanut, työn on päätettävä, haluaako se vastata peruutukseen. Kun yrität peruuttaa työtä, on kätevää odottaa, kunnes se käyttää join()-metodia. Seuraavassa on yleinen tapa peruuttaa työ ja odottaa, kunnes työ on valmis, ennen kuin jatketaan:
if (!job.cancel()) job.join();
Jos peruutus ei tule voimaan heti, cancel()-metodi palauttaa arvon false ja kutsuja käyttää join()-metodia odottaakseen työn peruutuksen onnistumista.
Peruutusta lievempi on sleep()-metodi. Tässä tapauksessa metodi pidättää työn toistaiseksi, jos työn ajo ei vielä ole alkanut. Ympäristö muistaa yhä työn ja wakeUp()-kutsu lisää työn odotusjonoon, josta se lopulta ajetaan.
Työ käy läpi useita tiloja elinkaarensa aikana. Sitä voivat käsitellä sovellusohjelmaliittymät, kuten cancel() ja sleep(), mutta sen tila voi muuttua myös ympäristön ajaessa työn ja työn tullessa valmiiksi. Työt voivat siirtyä seuraavien tilojen välillä:
Työn voi asettaa lepotilaan vain, jos se on parhaillaan WAITING-tilassa. Lepotilassa olevan työn herätys asettaa sen takaisin WAITING-tilaan. Työn peruutus palauttaa sen NONE-tilaan.
Jos lisäosan on tarpeen tietää tietyn työn tila, se voi rekisteröidä työn muutosten kuuntelutoiminnon, jolle ilmoitetaan, kun työ siirtyy elinkaarensa tilasta toiseen. Tämä on hyödyllistä, jos halutaan esittää työn tilatiedot tai muutoin raportoida työstä.
Job-metodin addJobChangeListener avulla voi rekisteröidä kuuntelutoiminnon tiettyyn työhön. IJobChangeListener määrittää käytännön työn tilan muutoksiin vastaamiseksi:
Kaikissa näistä tapauksista kuuntelutoiminnolla on IJobChangeEvent, joka määrittää tilan muutoksen kohdetyön ja sen valmistumisen tilan (jos se on valmis).
Huomautus: Työt määrittävät myös getState()-metodin, jonka avulla noudetaan työn (melko) ajantasainen tila. Tämä tulos ei kuitenkaan ole aina luotettava, koska työt ajetaan eri säikeissä ja niiden tila voi muuttua uudelleen siihen mennessä, kun kutsu palautuu. Töiden muutosten kuunteluohjelmat ovat suositeltu keino selvittää työn tilan muutokset.
IJobManager määrittää käytännön, jonka avulla voi käsitellä järjestelmän kaikkia töitä. Lisäosat, jotka näyttävät tilannetiedot tai muutoin käsittelevät työn rakennetta voivat tehdä IJobManager-kohteen avulla tehtäviä, kuten lykätä järjestelmän kaikki työt, selvittää ajossa olevan työn tai vastaanottaa tilatietojen palautetta tietyltä työltä. Ympäristön töiden hallintaohjelman voi noutaa Platform-sovellusohjelmaliittymän avulla:
IJobManager jobMan = Platform.getJobManager();
Lisäosat, jotka ovat kiinnostuneet järjestelmän kaikkien töiden tilasta, voivat rekisteröidä töiden muutosten kuuntelutoiminnon töiden hallintaohjelmaan sen sijaan, että rekisteröisivät kuuntelutoiminnot useisiin yksittäisiin töihin.
Joskus lisäosan on helpompaa käsitellä toisiinsa liittyvien töiden joukkoa yhtenä yksikkönä. Tämän voi tehdä työperheiden avulla. Työ määritetään kuuluvaksi tiettyyn perheeseen ohittamalla belongsTo-metodi:
public static final String MY_FAMILY = "myJobFamily"; ... class FamilyJob extends Job { ... public boolean belongsTo(Object family) { return family == MY_FAMILY; } }IJobManager-käytännön avulla voi peruuttaa, liittää, asettaa lepotilaan tai etsiä perheen kaikkia töitä:
IJobManager jobMan = Platform.getJobManager(); jobMan.cancel(MY_FAMILY); jobMan.join(MY_FAMILY, null);
Koska työperheet on esitetty minä tahansa objekteina, voit tallentaa kiinnostavan tilan työperheeseen itseensä, ja työt voivat koota perheobjekteja dynaamisesti tarpeen mukaan. On tärkeää käyttää melko yksilöllisiä perheobjekteja, jotta vältetään tahaton vuorovaikutus muiden lisäosien luomien perheiden kanssa.
Perheet ovat kätevä tapa paikallistaa työjoukkoja. IJobManager.find(Object family)-metodin avulla voi milloin tahansa paikallistaa kaikki ajossa olevien, odotustilassa olevien ja lepotilassa olevien töiden ilmentymät.