25 lipca 2012

Kilka ciekawostek z Java Concurrency API w Java 7 od Packt

Trudno mi było uwierzyć, że dałem się namówić na kolejną recenzję książki z wydawnictwa Packt. Nie jestem ich fanem, a ich książki są zwykle zbyt lekkie merytorycznie, aby kilka ciekawostek, których doszukanie się i tak zajmuje sporo czasu, było w stanie zrekompensować mój ból.

Tym razem jestem mile zaskoczony zawartością planowanej książki o współbieżności w Java 7 - Java 7 Concurrency Cookbook. Wydaje się być odpowiednio dopasowana merytorycznie do moich potrzeb, a że o współbieżności mowa (z którą mam niezwykle rzadko okazję się spotykać), tym lepiej dla niej (i mnie)!

Jako recenzent techniczny odpowiadam za jej właściwą zawartość merytoryczną i jakkolwiek pierwszy rozdział mógłbym z uciechą wrzucić do kosza, to kolejne zdają się bronić bez większego problemu.

Mam za sobą przeczytane 3 rozdziały (z ośmiu) i zaczynam z niecierpliwością oczekiwać lektury kolejnych. Właśnie w rozdziale 3 pojawiły się java.util.concurrent.CyclicBarrier oraz mój ulubieniec z Java 7 - j.u.c.Phaser.

Sposób przekazywania wiedzy przez autora nie nastraja do zagłębniania się w treść, a raczej służy jako zajawka do dalszego studiowania na własną rękę. Najbardziej "rozbraja" mnie prezentacja kodu źródłowego, który poszatkowany jest na kilkanaście punktów, które okraszone są skromnym opisem, często wręcz trywialnym nawet dla laika. Zatem, czytasz co będzie, demonstracja tego, co miało być i kolejny punkt. Dodając do tego, opisywanie konstrukcji "Stwórz klasę, która implementuje Runnable" i pojawia się kawałek początku klasy z "implements Runnable" i ręce opadają. Trzeba przywyknąć.

Z ciekawostek, które musiałem sprawdzić na własną rękę, zanim wprowadziłem zmiany w obecnej wersji, to klasa j.u.c.TimeUnit (którą swego czasu przedstawił mi Tomek Nurkiewicz), multi-catch oraz kombinacja TimeUnit z Phaser, a także j.u.Collections.nCopies.

Poniżej przykładowy kod, który służył jedynie celom sprawdzenia API. Nic ponadto! I niech tak zostanie.

package pl.japila.java7;

import java.util.Collections;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class Main {

    public static void main(String[] args) {
        System.out.println("Millis in a day: " + TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));
        System.out.println("Sleeping for 2 secs");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Collections.nCopies(3, true));
        CyclicBarrier barrier = new CyclicBarrier(1);
        try {
            barrier.await();
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
        Phaser phaser = new Phaser(2);
        try {
            phaser.awaitAdvanceInterruptibly(phaser.arrive(), 2, TimeUnit.SECONDS);
        } catch (InterruptedException | TimeoutException e) {
            e.printStackTrace();
        }
    }

}