28 sierpnia 2012

Zbiegi okoliczności wokół Android 4.1 Jelly Bean

Android 4.1, Jelly Bean "spotykam" na każdym kroku. Poza technicznymi detalami, które udaje mi się wyłapać podczas lektury artykułów, trafiłem ostatnio na informację o przygotowaniach do wydania Android 4.1 na Samsung Galaxy S II. Wcześniejsza zajawka o aktualizacji do 4.0.4 sprawiła, że przez tydzień sprawdzałem co godzinę, czy jest coś dostępnego. W przypadku Jelly Bean, odpuszczam. Na razie nie widzę powodów, abym potrzebował go. Jak będzie to będzie. I od razu mniej problemów na głowie.

A tu proszę. Wychodzę na spacer z Maksymem, a tu na telefonie informacja o dostępnej aktualizacji! Ni z gruszki ni z pietruszki pojawia się aktualizacja! Bajka!


Cóż było robić, aktualizacja ruszyła. Po 10 minutach telefon był już gotowy do ponownego użycia.


Jakby na dokładkę, w drodze powrotnej trafiłem na...


I jak to nazwać? Zbieg okoliczności? Próba zwrócenia na siebie uwagi? Ech, Androidzie, już do Ciebie wracam :)

26 sierpnia 2012

j.piknik z programowaniem funkcyjnym w Clojure

Koniec wakacji zbliża się nieuchronnie i widać ruch w interesie konferencyjnym. Najbliższa konferencja j.piknik już 30 sierpnia w Warszawie, podczas której wystąpię z tematem "Programowanie funkcyjne z Clojure (w przykładach)". Zaczynam o 16:20.

Celem prezentacji jest stworzenie prostego projektu w Clojure zarządzanego przez lein2 oraz informacyjnie konfiguracja dla Apache Maven 3, aby później użyć go w aplikacji javowej. W tej konfiguracji chciałbym pokazać, że elementy naszej aplikacji może być łatwiej oprogramować w Clojure, aby później użyć ich w głównej aplikacji javowej jako biblioteki zależne. Widać wyraźnie, że główny nacisk będę kierował do programistów javowych, których nosi w stronę języków alternatywnych. Sam ostatnio borykałem się z podobnym problemem (jak tu wprowadzić Clojure do projektu, w którym króluje Java) i wydaje mi się, że jest to podstawowy problem wielu z nas (= programistów javowych).
Jako środowiska programistyczne będą zaprezentowane Eclipse IDE + CCW (wtyczka do Clojure, Clojure REPL i informacyjnie Sublime Text 2.

Strona wydarzenia dostępna na facebooku.

Zachęcam do zadawania pytań w komentarzu, abym przygotowany mógł odpowiedzieć na nie podczas prezentacji lub po. Zapraszam i do zobaczenia!

17 sierpnia 2012

O tym jak DelayQueue realizuje kontrakt Iterable oraz BlockingQueue

W poprzednim wpisie Króciutko o j.u.concurrent.DelayQueue zaprezentowałem dosyć uproszczony przykład zastosowania java.util.concurrent.DelayQueue, w którym kolejka ukrywała elementy nieaktywne, co w tym konkretnym przypadku oznaczało wszystkie elementy. DelayQueue jest najzwyczajniej w świecie kolejką, która posiada dodatkową cechę, która pozwala na "widoczność" elementów, których czas "zamrożenia" minął. Stąd też, nieblokująca metoda poll() zwracała specjalną wartość - null - oznaczającą niemożność wykonania, tj. natychmiastowego zwrócenia elementu z kolejki.

Klasa j.u.c.DelayQueue posiada następujące cechy:
  • jest kolejką
  • jest nieograniczona (metoda remainingCapacity() zawsze zwraca Integer.MAX_VALUE)
  • jest blokująca (niektóre operacje manipulujące elementami kolejki, np. wspomniane poll() czy take())
  • operuje wyłącznie elementami typu j.u.concurrent.Delayed.
Zagłębiłem się w javadoc tej klasy i znalazłem inne ciekawostki, które przykuły moją uwagę. Oto przykład z nimi, a Twoim zadaniem jest odpowiedź na pytania w komentarzach. Miłej lektury!
package pl.japila.java7;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayQueueMain {

    static class Conference implements Delayed {

        long delay;

        public Conference(long delay) {
            this.delay = delay;
        }

        @Override
        public int compareTo(Delayed o) {
            Conference c = (Conference) o;
            return this.getDelay() < c.getDelay() ? -1 : this.getDelay() == c.getDelay() ? 0 : 1;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return getDelay();
        }

        public long getDelay() {
            return delay;
        }

        @Override
        public String toString() {
            return String.format("Conference starts in %s days", getDelay());
        }

    }

    public static void main(String[] args) {
        DelayQueue<Conference> conferences = new DelayQueue<Conference>();
        conferences.add(new Conference(5));
        conferences.add(new Conference(10));
        conferences.add(new Conference(15));

        System.out.println("Head (delay expired furthest in the past) element: " + conferences.poll());

        // Q1: Jakie elementy zostaną wypisane na ekran?
        for (Conference conf : conferences) {
            System.out.println(conf);
        }

        // Q2: Jaki efekt po wykonaniu poniższej linii?
        System.out.println(conferences.element());

        // Q3: Co się stanie tutaj?
        conferences.add(null);
    }

}

15 sierpnia 2012

Króciutko o j.u.concurrent.DelayQueue

Kolejny raz potwierdza się zasada, że kto czyta, nie błądzi. W przypadku pakietu java.util.concurrent możnaby powiedzieć, że jest to najbardziej nieprzestrzegana zasada, której hołduję od jakiegoś czasu i zamiast przysiąść nad dokumentacją javadoc, pozwalam sobie na poznawanie jej wyłącznie przy okazji i to w tak niewielkich dawkach, że byłoby grzechem nazwać je wykraczającymi przyzwoite minimum.

Na szczęście przyszło mi recenzować nadchodzącą książkę o java.util.concurrent - Java 7 Concurrency Cookbook z wydawnictwa Packt, więc chciał, czy nie chciał, jestem zaangażowany i poznaję.

Mojemu Maksymowi stuknęło 10 miesięcy! Postępy jakie robi we własnym rozwoju często są niezwykle zaskakujące i chciałbym móc to samo powiedzieć o swoim w kontekście j.u.concurrent. Przez ostatni miesiąc nauczył się sprawnie raczkować, siadać, wstawać, a nawet zaczyna chodzić asekurowany, czy to meblami czy przez inną osobę. Zaczyna mówić i od kilku dni daje się słyszeć blablabla, mama, czy inne dźwięki, których opisanie uważam za niemożliwe. Rozumie frazy: biedronka, nie, wypluj smoka, gdzie...?, lampa, daj, chodź, piciu piciu, am, otwórz buźkę i jeszcze kilka innych. Zaczęliśmy go przyzwyczajać do mycia zębów, bo przy 4 zębach i kolejnych 4 wychodzących, nie daje nam innego wyboru. Jada chętnie, dużo pije i ogólnie cacy. Oby tak dalej! A mówią, że nic nie trwa wiecznie :(

Gdyby przełożyć jego rozwój na mój w kontekście j.u.concurrent, to ja dopiero zacząłem raczkować. Pora to zmienić, bo za moment, to nie ja jego, ale on mnie będzie wychowywał. A jak Wam idzie poznawanie nowego API? Korzystacie z niego regularnie czy tylko z doskoku i to w ramach własnych, prywatnych projektów?

Na zakończenie krótki przykład z klasą, o istnieniu której dowiedziałem się właśnie z książki. Oto, proszę Państwa, wchodzi java.util.concurrent.DelayQueue. Trzeba było widzieć moją minę, kiedy przeczytałem o tej klasie, a nigdy wcześniej nawet słowa o niej nie czytałem. Niedobrze z moją znajomością Javki.

Pytanie kontrolne: Co będzie wypisane na ekran po uruchomieniu poniższej klaski?

package pl.japila.java7;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayQueueMain {

    static class Conference implements Delayed {

        long delay;

        public Conference(long delay) {
            this.delay = delay;
        }

        @Override
        public int compareTo(Delayed o) {
            Conference c = (Conference) o;
            return this.getDelay() < c.getDelay() ? -1 : this.getDelay() == c.getDelay() ? 0 : 1;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return delay;
        }

        public long getDelay() {
            return delay;
        }

    }

    public static void main(String[] args) {
        DelayQueue<Conference> conferences = new DelayQueue<Conference>();
        conferences.add(new Conference(5));
        conferences.add(new Conference(10));
        conferences.add(new Conference(15));

        System.out.println("Head (delay expired furthest in the past) element: " + conferences.poll());
    }

}