Java 5: Concurrency
Elokuu 1st, 2006
Genericseistä jo kirjoittelinkin, mutta ajattelin jatkaa toisella Java 5:n isolla parannuksella; nimittäin concurrency-paketilla [JSR-166].
Jos genericsien ajatuksena oli poistaa tarve casteilta ja instanceofeilta, niin concurrency-paketti pyrkii poistamaan Javasta seuraavat koodit:
- Object.wait, notify, notifyAll
- new Thread(Runnable).start();
- synchronized
Kirjoittelen ihan lyhyesti tällä kertaa; lähinnä niin, että ne jotka eivät ole tuohon tutustuneet, tietävät mistä on kyse ja mistä kannattaa hakea lisätietoa.
Aloitetaan vaikka perussäikeistyksellä.
Aiemmin uusi säie aloitettiin esimerkiksi seuraavasti: new Thread(Runnable).start(). Java 5:ssä sama tehdään suunnilleen seuraavasti:
private final ExecutorService executorService = Executors.newCachedThreadPool();
public void testGreet(final String name)
{
executorService.execute(new Runnable()
{
public void run()
{
System.out.println("Terve " + name);
}
});
}
Executor on siis uusi rajapinta, jonka avulla käytetty säikeistysmekanismi abstrahoidaan. Paketissa tulee mukana pari toteutusta, joiden instansseja saa kätevästi luotua Executors-apuluokan avulla. Näistä toinen, ScheduledThreadPoolExecutor, on siinä mielessä mielenkiintoinen, että sen avulla suoritukset voi ajastaa. Hieman kuin Timer, mutta poolattuna.
Sitten synchronized-blokkeihin. Uusi paketti tarjoaa paljon kattavammat käsittelyt erilaisille lukoille. Synchronized-blokki kun on vähän turhan järeä useimmissa synkronointitapauksissa. Suurimpina puutteina synchronized ei mahdollista odottavan säikeen vapautusta tai timeoutin asettamista.
Yksinkertaisimmassa tapauksessa koodia tulee taas vähän aiempaa enemmän:
private final Lock lock = new ReentrantLock();
public void testGreet()
{
lock.lock();
try
{
System.out.println("Vain yksi säie kerrallaan!");
}
finally
{
lock.unlock();
}
}
Noin. Mikä eniten varmaan pistää silmään, on finally-blokki, jotta lukko ei koskaan jää päälle. ReentrantLock sisältää varsin kattavan joukon erilaisia apumetodeja lukituksen hallintaan. Yksi mikä kannattaa muistaa on, että fair-järjestäminen on hitaampaa kuin ilman järjestystä suorittaminen.
Erityisen mielenkiintoinen on ReentrantReadWriteLock. Siinä on erillinen lukkonsa lukuoperaatioille ja oma muuttaville operaatioille. Lukot takaavat sen, ettei yksikään säie ole luku-blokin sisällä kun muutoksia tehdään. En nyt jaksa kirjoittaa tästä esimerkkiä, mutta ReadLockin ja WriteLockin saa siis ReentrantReadWriteLock-instanssilta.
Lukkoja voi nyt myös notifioida suoraan Condition-instanssien avulla. Conditionit liittyvät aina Lock-instanssiin, joka ne loi. Objectin wait-, notify- ja notifyAll-metodeilla ei ole mitään vaikutusta näiden toimintaan eli niiden kanssa kannattaa olla tarkkana. Conditionin metodit ovat await, signal ja signalAll erinäisine variaatioineen.
Asynkronisesti suoritettaville tehtäville lisättiin myös Swingistä tutun mallin mukaiset Callable ja Future-luokat. Callablen toteuttava luokka voi palauttaa arvon, joka on käsiteltävissä Future-instassin kautta. Toinen tapa on wräpätä Callable instanssi FutureTaskiin. Hyvät esimerkit löytyvät Future-luokan javadocista.
Concurrent-paketin mukana tuli myös uusia säieturvallisia kokoelmaluokkia (mm. “köyhän miehen JMS” eli Queue-rajapinta toteutuksineen ja aiemmin mainittua ReadWriteLockia käyttävä ConcurrentHashMap) sekä volatile-tyyliset toteutukset primitiiviluokkien wräppereille.
Säikeiden välinen kommunikaatio (tyyliin Stackless Python) ja synkronointi (CountDownLatch, CyclicBarrier, jne) jää nyt tällä kertaa selostamatta, kello on nimittäin sen verran… vähän.
Pitänee oikolukea nämä jorinat aamulla uudestaan…
Artikkeli on luettu 558 kertaa. Kuuluu luokkiin: Java, Ohjelmointi
1 Kommentti Lisää kommentti
1. Artti Jaakkola | Syyskuu 21st, 2006 at 19.10
Erittäin mielenkiintoinen säikeistysmalli on myös mm. Erlangin ja Scalan käyttämä Actor-malli. Lukkoja ei tarvita lainkaan, vaan kaikki säikeistys tapahtuu viestien välityksellä.
Jätä kommentti
Sallitut HTML-elementit:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed