单例模式(Singleton Pattern)

单例模式用于确保某个类全局只有一个实例。

单例模式的最基本的UML类图:

单例模式的最基本的代码示例:

 1 public class Singleton
 2 {
 3     private static Singleton instance = null;
 4 
 5     private Singleton() {};
 6 
 7     public static Singleton getInstance()
 8     {
 9         if(instance == null)
10         {
11             instance = new Singleton();
12         }
13         return instance;
14     }
15 }

对于上面的单例模型,如果对于单线程程序来说,不会存在什么问题,但是对于多线程可能会产生多个实例,对此我们有三种不同的实现方式

1. 饿汉实现,在声明静态属性的时候进行初始化,代码示例如下:

 1 public class EagerSingleton
 2 {
 3     private static EagerSingleton instance = new EagerSingleton();
 4 
 5     private EagerSingleton() {};
 6 
 7     public static EagerSingleton getInstance()
 8     {
 9         return instance;
10     }
11 }

对于这个实现在类第一次加载的时候,静态变量instance就会被初始话,保证了实例的的唯一性,不足之处,不能实现实例的延迟创建。

2. 懒汉实现,对get方法进行线程锁控制实现

 1 public class LazySingleton
 2 {
 3     private static LazySingleton instance = null;
 4 
 5     private LazySingleton() {};
 6 
 7     synchronized public static LazySingleton getInstance()
 8     {
 9         if(instance == null)
10         {
11             instance = new Singleton();
12         }
13         return instance;
14     }
15 }

懒汉模式通过synchronized关键字解决了线程安全问题,也实现了实例的延迟创建,但是需要检测线程锁对于高并发环境性能会大大降到。

3. IoDH实现(Initialization on Demand Holder),通过在单例类中增加增加静态内部类来实现

 1 public class IoDHSingleton
 2 {
 3     private static HolderClass
 4     {
 5         private final static IoDHSingleton instance = new IoDHSingleton();
 6     }
 7 
 8     private IoDHSingleton() {};
 9 
10     public static IoDHSingleton getInstance()
11     {
12         return HolderClass.instance;
13     }
14 }

对于这个实现既解决了线程安全问题,也实现了实例的延迟创建,但是不足之处很多面向对象语言不支持静态内部类的特性。

  此外,还有双重检测锁定的方式实现,但是由于双重检测锁定的方式中的,单例属性要加volatile关键字,而volatile关键字会屏蔽java虚拟机所做的一些代码优化,和锁定代码块会影响性能,所以也不是很少的方法,所以也就不做代码实现了。

  对于单例模式很多人说,单例模式长时间不用会被gc回收,我认为在Java中是不存在这种情况的,Java中单例模式创建的对象被自己类中的静态属性所引用,所以不会被回收。

 

posted on 2014-04-22 18:06  暮风吹雪  阅读(246)  评论(0编辑  收藏  举报

导航