java - singleton pattern

34
The Singleton Pattern …because we all use it but…

Upload: charles-casadei

Post on 30-Jun-2015

343 views

Category:

Software


0 download

DESCRIPTION

Another talk I gave at FastConnect, on the proper implementation of the Singleton Pattern in Java. Note : this talk was done prior to the release of Java 8

TRANSCRIPT

Page 1: Java - Singleton Pattern

The Singleton Pattern…because we all use it but…

Page 2: Java - Singleton Pattern

Singleton Pattern

Page 3: Java - Singleton Pattern

Singleton Pattern

1 & 1 instance

universal access

prevents/controlsconcurrency

Page 4: Java - Singleton Pattern

Singleton Pattern

logging

databaseaccess

class loaders

factories

Page 5: Java - Singleton Pattern

Basic Singleton

Page 6: Java - Singleton Pattern

Basic Singleton

no new

utility method

static method

static instance

Page 7: Java - Singleton Pattern

Basic Singleton

// Minimal Singleton (or is it ?), can’t handle pre-conditionspublic class Singleton {

private static final Singleton INSTANCE = new Singleton();

private Singleton() {if (INSTANCE != null) {

throw new IllegalStateException("Woops, the matrix is broken");}

}

public static Singleton getInstance() {return INSTANCE;

} }

Page 8: Java - Singleton Pattern

Basic Singleton

// Same as before, can handle pre-conditions through static init. blockpublic class Singleton {

private static Singleton INSTANCE;

static {try {

INSTANCE = new Singleton();} catch (Exception ex) {

throw new RuntimeException("A damn error occured!", ex);}

}

private Singleton() {// Same as before

}public static Singleton getInstance() {

return INSTANCE;}

}

Page 9: Java - Singleton Pattern

Broken Idioms

Page 10: Java - Singleton Pattern

Broken IdiomsInstance not initialized, no sync

// Seems right, at first, but what about concurrency ?public class Singleton {

private static Singleton INSTANCE = null;

private Singleton() {// Nothing

}

public static Singleton getInstance() {if (INSTANCE == null) {

INSTANCE = new Singleton();}return INSTANCE;

}}

Page 11: Java - Singleton Pattern

Broken IdiomsSynchronized getInstance()

// Concurrency issue fixed, but very slowpublic class Singleton {

private static Singleton INSTANCE = null;

private Singleton() {// Nothing

}

public static synchronized Singleton getInstance() {if (INSTANCE == null) {

INSTANCE = new Singleton();}return INSTANCE;

}}

Page 12: Java - Singleton Pattern

Broken IdiomsDouble checked locking

// Does not work this way, broken due to compiler re-orderingpublic class Singleton {

private static Singleton INSTANCE = null;

private Singleton() { }

public static Singleton getInstance() {if (INSTANCE == null) {

synchronized (Singleton.class) {if (INSTANCE == null) {

INSTANCE = new Singleton();}

}}return INSTANCE;

}}

Page 13: Java - Singleton Pattern

Basic Singleton 2

Page 14: Java - Singleton Pattern

Basic Singleton 2The Holder, proposed by Bill Pugh

//No language construct, relies on JVM memory model properties, very lazypublic class Singleton {

private Singleton() {// Nothing

}

// Loaded on the 1st exec of Singleton.getInstance(), not beforeprivate static class SingletonHolder {

public static final Singleton INSTANCE = new Singleton();}

public static Singleton getInstance() {return SingletonHolder.INSTANCE;

}}

Page 15: Java - Singleton Pattern

Enum Singleton

Page 16: Java - Singleton Pattern

Enum Singletonhave

methods

can implements

interface

static instances

free

thread safe*

* only if there is no

state

serializable

Page 17: Java - Singleton Pattern

Enum SingletonProposed by Joshua Bloch

// OK in most cases, can be hacked by malicious serialized formpublic enum Elvis implements Singer, Zombie {

ELVIS;

@Overridepublic void singASong() {

// …}

@Overridepublic void eatBrains() {

// …}

}

Page 18: Java - Singleton Pattern

SerializableSingleton

Page 19: Java - Singleton Pattern

Enum Singleton

NO STATE

Page 20: Java - Singleton Pattern

SerializableSingletonPart 1

public class Elvis implements Serializable {private static final Elvis INSTANCE = new Elvis();private static final long serialVersionUID = 42L;private volatile String[] songs = {"Hound Dog", "Heartbreak Hotel"};

public static Elvis getInstance() { return INSTANCE; }private Elvis() { }

public void leaveTheBuilding() { }

public void setFavouriteSongs(String[] songs) {this.songs = songs.clone();

}

public void printFavorites() {System.out.println(Arrays.toString(songs));

}

Page 21: Java - Singleton Pattern

SerializableSingletonPart 2

// this should never be invokedprivate Object readResolve() {

return INSTANCE;}

private void readObject(ObjectInputStream ex) throws IOException {throw new InvalidObjectException("Cannot load another Elvis");

}

private Object writeReplace() {return new ElvisSerializableForm(songs);

}

Page 22: Java - Singleton Pattern

SerializableSingletonPart 3

private Object writeReplace() {return new ElvisSerializableForm(songs);

}

private static class ElvisSerializableForm implements Serializable {

private final String[] songs;

public ElvisSerializableForm(String[] favoriteSongs) {this.songs = favoriteSongs;

}

public Object readResolve() {Elvis.INSTANCE.setFavouriteSongs(songs);return Elvis.INSTANCE;

}}

}

Page 23: Java - Singleton Pattern

Singletons are Armful

Page 24: Java - Singleton Pattern

Singletons are Armful

global state

hard to test

hard codeddependencies

Similar to Village of the

Damned

design anti-pattern

Might be OK if there is NO

STATE

use IoC for factories

Page 25: Java - Singleton Pattern

Singletons

Page 26: Java - Singleton Pattern

Singletons

Use enums

Use « Lazy Holders »

Beware of Serialization

Singleton are Armful

Don’t use them

Page 27: Java - Singleton Pattern

Singletons

Page 28: Java - Singleton Pattern

QuizzFixing the broken ones

Page 29: Java - Singleton Pattern

A double fixFixing double checked locking

// Does not work this way, broken due to compiler re-orderingpublic class Singleton {

private static Singleton INSTANCE = null;

private Singleton() { }

public static Singleton getInstance() {if (INSTANCE == null) {

synchronized (Singleton.class) {if (INSTANCE == null) {

INSTANCE = new Singleton();}

}}return INSTANCE;

}}

Page 30: Java - Singleton Pattern

A double fixFixing double checked locking

// The right word, at the right time, in the right place can make a differencepublic class Singleton {

private static volatile Singleton INSTANCE = null;

private Singleton() { }

public static Singleton getInstance() {if (INSTANCE == null) {

synchronized (Singleton.class) {if (INSTANCE == null) {

INSTANCE = new Singleton();}

}}return INSTANCE;

}}

Page 31: Java - Singleton Pattern

Biblio

Page 32: Java - Singleton Pattern

Biblio

Bloch, Joshua. Effective Java, Second Edition. O’Reilly, 2008

Croisier, Olivier. De la bonne implémentation du Singleton en Java. 2008. http://thecodersbreakfast.net/index.php?post/2008/02/25/26-de-la-bonne-implementation-du-singleton-en-java

Hevery, Miško. Root Cause of Singletons, 2008. http://misko.hevery.com/2008/08/25/root-cause-of-singletons/

Hevery, Miško. Singleton are Pathlogical Liars, 2008. http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/

Page 33: Java - Singleton Pattern

Biblio

Hevery, Miško. Where Have All the Singletons Gone ?, 2008. http://misko.hevery.com/2008/08/21/where-have-all-the-singletons-gone/

Kabutz, Heinz. The Java Specialists’ Newsletter #163, 2008. http://www.javaspecialists.eu/archive/Issue163.html

Manson, Jeremy. Double Checked Locking, 2008. http://jeremymanson.blogspot.fr/2008/05/double-checked-locking.html

Pugh, Bill. The « Double-Checked Locking is Broken » Declaration. http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

Page 34: Java - Singleton Pattern

Biblio

Pugh, Bill. The Java Memory Model, 2004. http://www.cs.umd.edu/~pugh/java/memoryModel/

Pugh, Bill. JSR 133 (Java Memory Model) FAQ, 2004. http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html

Wikipedia, Initialization-on-demand holder idiom. http://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom

Wikipedia, Singleton pattern. http://en.wikipedia.org/wiki/Singleton_pattern