Lintcode: Singleton && Summary: Synchronization and OOD
Singleton is a most widely used design pattern. If a class has and only has one instance at every moment, we call this design as singleton. For example, for class Mouse (not a animal mouse), we should design it in singleton. You job is to implement a getInstance method for given class, return the same instance of this class every time you call this method. Example In Java: A a = A.getInstance(); A b = A.getInstance(); a should equal to b. Challenge If we call getInstance concurrently, can you make sure your code could run correctly?
单例模式,这是一道OOD的题
Eager initialization
This is a design pattern where an instance of a class is created much before it is actually required. Mostly it is done on system start up. In singleton pattern, it refers to create the singleton instance irrespective of whether any other class actually asked for its instance or not.
1 public class EagerSingleton { 2 private static volatile EagerSingleton instance = new EagerSingleton(); 3 4 // private constructor 5 private EagerSingleton() { 6 } 7 8 public static EagerSingleton getInstance() { 9 return instance; 10 } 11 }
Above method works fine, but has one drawback. Instance is created irrespective of it is required in runtime or not. If this instance is not big object and you can live with it being unused, this is best approach.
Lets solve above problem in next method.
Lazy initialization
In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. In singleton pattern, it restricts the creation of instance until requested first time. Lets see in code:
1 public final class LazySingleton { 2 private static volatile LazySingleton instance = null; 3 4 // private constructor 5 private LazySingleton() { 6 } 7 8 public static LazySingleton getInstance() { 9 if (instance == null) { 10 synchronized (LazySingleton.class) { 11 instance = new LazySingleton(); 12 } 13 } 14 return instance; 15 } 16 }
On first invocation, above method will check if instance is already created using instance variable. If there is no instance i.e. instance is null, it will create an instance and will return its reference. If instance is already created, it will simply return the reference of instance.
But, this method also has its own drawbacks. Lets see how. Suppose there are two threads T1 and T2. Both comes to create instance and execute “instance==null”, now both threads have identified instance variable to null thus assume they must create an instance. They sequentially goes to synchronized block and create the instances. At the end, we have two instances in our application.
This error can be solved using double-checked locking. This principle tells us to recheck the instance variable again in synchronized block in given below way:
Double-Checking Locking: (correct version)
1 public class EagerSingleton { 2 private static volatile EagerSingleton instance = null; 3 4 // private constructor 5 private EagerSingleton() { 6 } 7 8 public static EagerSingleton getInstance() { 9 if (instance == null) { 10 synchronized (EagerSingleton.class) { 11 // Double check 12 if (instance == null) { 13 instance = new EagerSingleton(); 14 } 15 } 16 } 17 return instance; 18 } 19 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架