Java - Singleton Pattern

779 views

Published on

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

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
779
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
21
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Java - Singleton Pattern

  1. 1. TheSingleton Pattern …because we all use it but…
  2. 2. Singleton Pattern
  3. 3. Singleton Pattern 1 & 1 instance universal access prevents/controls concurrency
  4. 4. Singleton Pattern logging database access class loaders factories
  5. 5. Basic Singleton
  6. 6. BasicSingleton no new utility method static method static instance
  7. 7. BasicSingleton // Minimal Singleton (or is it ?), can’t handle pre-conditions public 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; } }
  8. 8. BasicSingleton // Same as before, can handle pre-conditions through static init. block public 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; } }
  9. 9. Broken Idioms
  10. 10. Broken Idioms Instance 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; } }
  11. 11. Broken Idioms Synchronized getInstance() // Concurrency issue fixed, but very slow public class Singleton { private static Singleton INSTANCE = null; private Singleton() { // Nothing } public static synchronized Singleton getInstance() { if (INSTANCE == null) { INSTANCE = new Singleton(); } return INSTANCE; } }
  12. 12. Broken Idioms Double checked locking // Does not work this way, broken due to compiler re-ordering public 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; } }
  13. 13. Basic Singleton 2
  14. 14. Basic Singleton 2 The Holder, proposed by Bill Pugh //No language construct, relies on JVM memory model properties, very lazy public class Singleton { private Singleton() { // Nothing } // Loaded on the 1st exec of Singleton.getInstance(), not before private static class SingletonHolder { public static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }
  15. 15. EnumSingleton
  16. 16. EnumSingleton have methods can implements interface static instances free thread safe* * only if there is no state serializable
  17. 17. EnumSingleton Proposed by Joshua Bloch // OK in most cases, can be hacked by malicious serialized form public enum Elvis implements Singer,Zombie { ELVIS; @Override public void singASong() { // … } @Override public void eatBrains() { // … } }
  18. 18. Serializable Singleton
  19. 19. EnumSingleton NO STATE
  20. 20. Serializable Singleton Part 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)); }
  21. 21. Serializable Singleton Part 2 // this should never be invoked private 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); }
  22. 22. Serializable Singleton Part 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; } publicObject readResolve() { Elvis.INSTANCE.setFavouriteSongs(songs); return Elvis.INSTANCE; } } }
  23. 23. Singletons are Armful
  24. 24. Singletons are Armful global state hard to test hard coded dependencies Similar to Village of the Damned design anti- pattern Might be OK if there is NO STATE use IoC for factories
  25. 25. Singletons
  26. 26. Singletons Use enums Use « Lazy Holders » Beware of Serialization Singleton are Armful Don’t use them
  27. 27. Singletons
  28. 28. Quizz Fixing the broken ones
  29. 29. A double fix Fixing double checked locking // Does not work this way, broken due to compiler re-ordering public 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; } }
  30. 30. A double fix Fixing double checked locking //The right word, at the right time, in the right place can make a difference public 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; } }
  31. 31. Biblio
  32. 32. Biblio  Bloch, Joshua. EffectiveJava,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/
  33. 33. 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/DoubleChecke dLocking.html
  34. 34. 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

×