创建模式之单例模式

       在面试时经常会有人问单例模式,单例模式是在整个系统运行中仅且仅有一个实例,在被调用。我们熟知的Calendar就是这种,

       Calendar.newInstance()获取实例。此时,构造器要设置为private,防止被new实例。连接池也是整个系统仅有一个,采用单例模式,但连接池中的每条连接却采用原型模式创建。

       单例模式因被整个系统运行,因此不能存在可被修改的实例变量。另外SpringMvc中的Controller和Service都为单例模式。

       而Struts中的Controller为原型模式。

1.单例模式-饿汉加载

    饿汉模式:在系统创建,启动时创建对象。由于静态变量的声明在编译时已经明确,因此在系统装载时就已经产生。不牵涉线程安全问题。

 1 public class SingletonModel {
 2 
 3     private static final SingletonModel singleton = new SingletonModel();
 4     
 5     /**
 6      * 私有化构造实例
 7      */
 8     private SingletonModel(){
 9     }
10     
11     public static SingletonModel newInstance(){
12         return singleton;
13     }
14 }
饿汉模式加载

      采用静态代码段方式

1 private static SingletonModel singleton = null;
2     static{
3         singleton = new SingletonModel();
4     }
静态代码块

2.单例模式-懒汉加载

    懒汉模式:在第一次被调用的时候创建。

 1 public class SingletonModel {
 2 
 3     private static SingletonModel singleton = null;
 4     
 5     /**
 6      * 私有化构造实例
 7      */
 8     private SingletonModel(){
 9     }
10     
11     public static SingletonModel newInstance(){
12         if(singleton == null){
13             singleton = new SingletonModel();
14         }
15         return singleton;
16     }
17 }
懒汉加载

2.1 因用newInstance的方式,不适合多线程,而如果给newInstance方法加 synchronized同步锁(如示例1),但是同步又牵扯到性能,如果每一个线程都先做这个操作,就没有必要。

2.2 给代码块添加同步锁(如示例2),这种情况又会牵扯一个问题,就是A线程判断instance为null时,B线程也判断出instance为null,此时A单线程处理,B在等待,A创建对象完后,同步锁释放,B因为已经进入instance为null的里面,因此也会创建对象。为此需要进行双验证,即双保险。(如示例3)

1 public static synchronized SingletonModel newInstance(){
示例1
1 public static  SingletonModel newInstance(){
2         if(singleton == null){
3             synchronized(SingletonModel.class){
4                 singleton = new SingletonModel();
5             }
6         }
7         return singleton;
8     }
示例2
 1     public static  SingletonModel newInstance(){
 2         if(singleton == null){
 3             synchronized(SingletonModel.class){
 4                 if(singleton == null){
 5                     singleton = new SingletonModel();
 6                 }
 7             }
 8         }
 9         return singleton;
10     }
示例3

 

参考文摘:

( java设计模式学习系列之一:单例模式(Singleton))http://blog.csdn.net/qjyong/article/details/1721342

(五种方法实现Java的Singleton单例模式)http://www.cnblogs.com/pkufork/p/java_singleton.html

------------------------------------------------------------------------------------------------------------------------------

 如有纰漏之处,还望指正。

                                         ---DennyZhao

posted on 2017-06-19 16:29  zhaoqiang1980  阅读(152)  评论(0编辑  收藏  举报