160 likes | 334 Views
Computer Science 313 – Advanced Programming Topics. Lecture 18: Singleton Implementation. Singleton Pattern. Pattern when system uses 1 instance of the class Allocates only 1 instance during program Constructor private, so cannot allocate second instance
E N D
Computer Science 313 – Advanced Programming Topics Lecture 18:Singleton Implementation
Singleton Pattern • Pattern when system uses 1 instance of the class • Allocates only 1 instance during program • Constructor private, so cannot allocate second instance • Methods unrestricted and can be defined however • Similarly, pattern places no limits on fields’ values • Use static method for reference to instance • Since it is staticcan call method anywhere • Could store reference in other classes, but… • … would make tracking uses & debugging difficult
Singleton Pattern Guides Do not use for • 1 instance wanted • Global value • Instead use static field • Poor design suggested • Instantiation check • Use factory method Do use for • 1 instance possible • Global access point • For a global resource • Gatekeeper for actions • Optimize performance • Can be easily removed
Common Themes in Singleton • Every Singleton includes following members • static field holding the instance • To get instance defines publicstaticmethod • Singleton usually includes this member also • Limit instantiation defining private constructor • May include in class, but much rarer • Allow subclassing with protected constructor • Getter as simple factory also found in this case
How To Create Factory Singleton public class GameFactory {private static GameFactoryme;protected GameFactory() { }public static GameFactoryinstance(intuserAge){if (me == null) { if (userAge < 13)me = new AnimatedGameFactory(); else me = new HardCoreGameFactory();} return me;} }
Oops, Our Bad… public class PrinterSpool {private static PrinterSpoolme;privatePrinterSpool() { }public static PrinterSpoolinstance() {if (me == null) {me = new PrinterSpool(); }returnme;} }
Synchronization is Hard • Synchronization veryexpensive • Insures only 1 instance created • Must remain usable or program not helpful • Even best design meaningless if too slow • 4 ways to hide costs of synchronization • Each way shifts where costs occur • Minimize costs for how code used
When Method Rarely Called • Explicit, but expensive, synchronization used public class Engine {private static Engine me;private Engine() { }public static Engine instance() { if (me == null) { me = new Engine(); } return me;} }
When Method Rarely Called • Explicit, but expensive, synchronization used • Synchronized routines performed at each call public class Engine {private static Engine me;private Engine() { }public static synchronized Engine instance() { if (me == null) { me = new Engine(); } return me;} }
When Instantiation is Cheap • Uses system’s implicit synchronization public class Engine {private static Engine me;private Engine() { }public static Engine instance() { if (me == null) { me = new Engine(); } return me;} }
When Instantiation is Cheap • Uses system’s implicit synchronization • Eagerly create instance & keep it until needed public class Engine {private static Engine me = new Engine();private Engine() { }public static Engine instance() { return me;} }
For Use on Any JVM • Also uses system’s implicit synchronization public class Engine {private static Engine me;private Engine() { }public static Engine instance() { if (me == null) { me = new Engine(); } return me;} }
For Use on Any JVM • Also uses system’s implicit synchronization • But delays creation instance until needed public class Engine {private class EngineHolder { private static Engine instance=new Engine();}private static Engine me;private Engine() { }public static Engine instance() { return EngineHolder.instance;} }
On Modern (1.5+) JVMs • Double-locking only costs on instance creation public class Engine {private static Engine me;private Engine() { }public static Engine instance() { if (me == null) { me = new Engine(); } return me;} }
On Modern (1.5+) JVMs • Double-locking only costs on instance creation • Accessing static field expensive for rest of program public class Engine {private volatilestatic Engine me;private Engine() { }public static Engine instance() { if (me == null)synchronized (Engine.class) { if (me == null) { me = new Engine(); }} return me;} }
For Next Class • Lab #4 on Angel • Have 1.5 weeks left to complete this lab • Do not delay, it will take time to complete • Midterm #1 in class on Friday • Open-book, open-note exam (as usual) • Use any lecture’s slides IF you have notes on them • No computers, calculators, or friends, however