Multiton & Singleton
From J2EE Bloger http://j2eeblogger.blogspot.com/2007/10/singleton-vs-multiton-synchronization.html
1. Classic Java singleton synchronization problem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class Singleton { private static Singleton instance; /** Prevents instantiating by other classes. */ private Singleton(){} public static synchronized Singleton getInstance() { if (instance == null ){ instance = new Singleton(); } return instance; } } |
The synchronized keyword on the getInstance() method is the evil. In a multi-thread environment, every thread will be blocked by each other when trying to grab the singleton instance. This is the classic java singleton synchronization problem.
2. The traditional solution using a static variable.
1 2 3 4 5 6 7 8 9 10 | public class Singleton { /** Prevents instantiating by other classes. */ private Singleton() {} private final static Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } } |
The singleton instance is initialized during the class loading time. No synchronization is necessary on the getInstance level.
3. The classic synchronized multiton.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class Multiton { private static final HashMap<Object, Multiton> instances = new HashMap<Object, Multiton>(); private Multiton(){} public static Multiton getInstance(Object key){ synchronized (instances) { // Our "per key" singleton Multiton instance; if ((instance = instances.get(key)) == null ) { // Lazily create instance and add it to the map instance = new Multiton(); instances.put(key, instance); } return instance; } } } |
The Multiton pattern begins with the concept of the Singleton pattern and expands it into an object pool of keys to objects. Instead of having a single instance per runtime, the Multiton pattern ensures a single instance per key. It simplifies retrieval of shared objects in an application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class Multiton { private static final HashMap<Object, Multiton> instances = new HashMap<Object, Multiton>(); public static Multiton getInstance(Object key) { // Our "per key" singleton Multiton instance; if ((instance = instances.get(key)) == null ) { synchronized (instances) { if ((instance = instances.get(key)) == null ) { instance = new Multiton(); instances.put(key, instance); } } } return instance; } } |
Yes the double-checked locking does not work for Singleton (http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html), but it does work for our Multiton pattern. Reason? We have our intermediate HashMap object sits in between. Actually we can use the HashMap to solve the Singleton double-checked locking problem as well, if we don't already have the more elegant solution using a static variable.
5. An alternative solution: Using the Java 5 ConcurrentMap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class Multiton { private static final ConcurrentMap<Object, Multiton> instances = new ConcurrentHashMap<Object, Multiton>(); public static Multiton getInstance(Object key) { // Our "per key" singleton if (instances.get(key) == null ) { // Lazily create instance and try to add it to the map Multiton instance = new Multiton(); instances.putIfAbsent(key, instance); } return instances.get(key); } } |
The Java 5 ConcurrentMap.putIfAbsent(), being an atomic operation, returns the previous value associated with the key instead of the new suggested value. This ensures the uniqueness of the Multiton instance inside the ConcurrentMap.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)