Zielony Smok - logo witryny

Zadanie programistyczne 1

Stworzyć klasę KrolSmokow. Król Smoków może być tylko jeden, więc klasa nie
może pozwolić na utworzenie więcej niż jednej instancji.

Rozwiązanie 1

Konstruktor jest prywatny więc nie można utworzyć instancji przez użycie new
poza samą klasą. Można utworzyć instancje przez wywołanie statycznej metody
getInstance().

Klasa KrolSmokow
package singleton.classic;
public class KrolSmokow {
    private static KrolSmokow uniqueInstance;
    private KrolSmokow() {
        System.out.print("Jestem Królem Smoków");
    }
    public static KrolSmokow getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new KrolSmokow();
        }
        return uniqueInstance;
    }
}
Klasa Main1
package singleton.classic;
class Main1 {
    public static void main(String[] args) {
        KrolSmokow.getInstance();
        KrolSmokow.getInstance();//ta instancja nie zostaje utworzona
    }
}
Wynik
Jestem Królem Smoków

Klasa ta nie jest bezpieczna wątkowo, gdyż kiedy konkurujące wątki
próbowały by jednocześnie utworzyć instancję, jest możliwe, że została by
utworzona więcej niż jedna instancja. Jeśli nie ma współbieżności – ten sposób jest
wystarczający.

Zadanie programistyczne 2

Stworzyć klasę KrolSmokow, nie pozwalając wrogom – w żadnych warunkach – na
utworzenie sobowtóra: drugiego Króla Smoków.

Rozwiązanie 2

Klasa KrolSmokow
package singleton.threadsafe;
public class KrolSmokow {
    private static KrolSmokow uniqueInstance;
    private KrolSmokow() {
        System.out.print("Jestem Królem Smoków");
    }
    public static synchronized KrolSmokow getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new KrolSmokow();
        }
        return uniqueInstance;
    }
}
Klasa Main2
package singleton.threadsafe;
class Main2 {
    public static void main(String[] args) {
        KrolSmokow.getInstance();
        KrolSmokow.getInstance();
    }
}
Wynik
Jestem Królem Smoków

Zadanie programistyczne 3

Synchronizacja jest potrzebna tylko w momencie utworzenia, potem niepotrzebnie
obciąża koszty ochrony Króla. Utworzyć Króla Smoków w momencie inicjalizacji
klasy. JVM zapewni utworzenie jednego obiektu co pozwala na pominięcie
synchronizacji.

Rozwiązanie 3

Klasa KrolSmokow
package singleton.nothreads;
public class KrolSmokow {
    private static final KrolSmokow uniqueInstance = new KrolSmokow();
    private KrolSmokow() {
        System.out.println("Jestem Królem Smoków");
    }
    public static KrolSmokow getInstance() {
        return uniqueInstance;
    }
}
Klasa Main3
package singleton.nothreads;
class Main3 {
    public static void main(String[] args) {
        KrolSmokow.getInstance();
        KrolSmokow.getInstance();
    }
}
Wynik
Jestem Królem Smoków

Zadanie programistyczne 4

Synchronizacja jest potrzebna tylko w momencie utworzenia, potem niepotrzebnie
obciąża procesor.

Utworzyć Króla Smoków przez zapewnienie synchronizacji tylko wtedy, gdy
go jeszcze nie ma. Gdy jest – następuje zwrócenie instancji bez synchronizacji.

Rozwiązanie 4

Klasa KrolSmokow
package singleton.threadsafe2;
public class KrolSmokow {
    private volatile static KrolSmokow uniqueInstance;
    private KrolSmokow() {
        System.out.println("Jestem Królem Smoków");
    }
    public static KrolSmokow getInstance() {
        if (uniqueInstance == null) {
            synchronized (KrolSmokow.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new KrolSmokow();
                }
            }
        }
        return uniqueInstance;
    }
}
Klasa Main4
package singleton.threadsafe2;
class Main4 {
    public static void main(String[] args) {
        KrolSmokow.getInstance();
        KrolSmokow.getInstance();
    }
}
Wynik
Jestem Królem Smoków

Zadanie programistyczne 5

Pozwolić Królowi Smoków na posiadanie potomka, czyli tak aby mogły istnieć dwa i tylko dwa
obiekty: Król i Pierworodny.

Rozwiązanie 5

Klasa KrolSmokow
package singleton.potomek;
public class KrolSmokow {
    private static KrolSmokow uniqueInstance;
    KrolSmokow() {
        System.out.println("Jestem Królem Smoków");
    }
    public static synchronized KrolSmokow getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new KrolSmokow();
        }
        return uniqueInstance;
    }
}
Klasa Pierworodny
package singleton.potomek;
class Pierworodny extends KrolSmokow {
    protected static KrolSmokow uniqueInstance;
    private Pierworodny() {
        super();
    }
}
Klasa Main5
package singleton.potomek;
class Main5 {
    public static void main(String[] args) {
        KrolSmokow.getInstance();
        KrolSmokow syn1 = Pierworodny.getInstance();
        System.out.println(syn1);
    }
}
Wynik
Jestem Królem Smoków
singleton.potomek.KrolSmokow@2ef9b8bc