在Java设计模式中,单例模式相对来讲算是比较简单的一种构建模式。适用的场景在于:对于定义的一个类,在整个应用程序执行期间只有惟一的一个实例对象。如Android中常见的Application对象。java
经过单例模式,自行实例化并向这个系统提供这个单一实例的访问方法。设计模式
根据此单一实例产生的时机不一样(固然,都是指第一次,也是惟一一次产生此单一实例时),能够将其分为懒汉式、饿汉式和登记式。安全
1、懒汉式:多线程
其特色是延迟加载,即当须要用到此单一实例的时候,才去初始化此单一实例。常见经典的写法以下:函数
1 package com.qqyumidi; 2
3 public class SingleTon { 4
5 // 静态实例变量
6 private static SingleTon instance; 7
8 // 私有化构造函数
9 private SingleTon() { 10
11 } 12
13 // 静态public方法,向整个应用提供单例获取方式
14 public static SingleTon getInstance() { 15 if (instance == null) { 16 instance = new SingleTon(); 17 } 18 return instance; 19 } 20
21 }
懒汉式的线程安全写法ui
1 package com.qqyumidi; 2 3 public class SingleTon { 4 5 // 静态实例变量加上volatile 6 private static volatile SingleTon instance; 7 8 // 私有化构造函数 9 private SingleTon() { 10 11 } 12 13 // 双重检查锁 14 public static SingleTon getInstance() { 15 if (instance == null) { 16 synchronized(Singleton.class){ 17 if(instance == null){ 18 instance = new SingleTon(); 19 } 20 } 21 } 22 return instance; 23 } 24 25 }
2、饿汉式:spa
饿汉式的特色是应用中还没有须要用到此单一实例的时候即先实例化。常见的经典写法为:线程
1 package com.qqyumidi; 2
3 public class SingleTon { 4
5 // 静态实例变量,直接初始化
6 private static SingleTon instance = new SingleTon(); 7
8 // 私有化构造函数
9 private SingleTon() { 10
11 } 12
13 // 静态public方法,向整个应用提供单例获取方式
14 public static SingleTon getInstance() { 15 return instance; 16 } 17
18 }
3、登记式单例模式:设计
登记式单例模式,通常是经过一个专门的类对各单例模式的此单一实例进行管理和维护。经过Map方式能够方便的实现此中目的。常见的代码以下:code
1 package com.qqyumidi; 2
3 import java.util.HashMap; 4 import java.util.Map; 5
6 public class SingleTonManager { 7
8 private static Map singleTonMap = new HashMap(); 9
10 public static void main(String[] args) { 11 // 获取A类的单例
12 A a = (A) getInstance(A.class.getName()); 13 // 获取B类的单例
14 B b = (B) getInstance(B.class.getName()); 15 } 16
17 // 根据类型获取单例
18 public static Object getInstance(String className) { 19 // 判断singleTonMap中是否有此单例,有则取得后返回,无则添加单例后返回
20 if (!singleTonMap.containsKey(className)) { 21 try { 22 singleTonMap.put(className, Class.forName(className).newInstance()); 23 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { 24 // TODO Auto-generated catch block
25 e.printStackTrace(); 26 } 27 } 28 return singleTonMap.get(className); 29 } 30 } 31
32 class A { 33
34 } 35
36 class B { 37
38 }
另外:须要注意的是,在多线程环境中,以上各类方法构造单例模式须要考虑到线程安全问题。
4、改进型懒汉式(直接知足线程安全)——经过静态内部类实现
在如上的懒汉单例模式中,对于多线程环境中。能够经过常见的如synchronized等方式实现线程安全,同时,能够经过Java静态内部类的方式实现进一步改进。
常见代码以下:
1 package com.qqyumidi; 2
3 public class SingleTon { 4
5 // 利用静态内部类特性实现外部类的单例
6 private static class SingleTonBuilder { 7 private static SingleTon singleTon = new SingleTon(); 8 } 9
10 // 私有化构造函数
11 private SingleTon() { 12
13 } 14
15 public static SingleTon getInstance() { 16 return SingleTonBuilder.singleTon; 17 } 18
19 public static void main(String[] args) { 20 SingleTon instance = getInstance(); 21 } 22 }
其主要原理为:Java中静态内部类能够访问其外部类的成员属性和方法,同时,静态内部类只有当被调用的时候才开始首次被加载,利用此特性,能够实现懒汉式,在静态内部类中静态初始化外部类的单一实例便可。