设计模式之单例模式

单例模式属于“创建型”模式,“创建型”模式主要讲对象的创建方法,单例模式有两种实现方式:饿汉式、懒汉式;下面对这两种实现方式加以总结。

1、饿汉式单例:

单例类在自己类内部定义自己的实现,注意构造函数的访问类型是private,这样外界没有创建单例类的方法,只能通过一个静态的getObj()方法来获得该单例的对象,而getObj()方法返回的对象是早已创建好的自身对象,无论调用多少次,返回的都是同一个对象,你可以通过set方法修改对象的属性值,但是reference引用指向的对象一直是同一个对象。

 1 class Singleton{//可以用final修饰,也可以不用
 2     private int val;
 3     private static Singleton reference=new Singleton(23);//定义自己的实现
 4     private Singleton(int val){
 5         this.val=val;
 6     }
 7     public static  Singleton getObj(){
 8         return reference;
 9     }
10     public void setVal(int val){
11         this.val=val;        
12     }
13     public int getVal(){
14         return this.val;        
15     }
16 }

2、懒汉式单例:

所谓“懒汉式”就是在我们需要单例对象的时候才给创建单例对象,而“饿汉式”是对象早已创建好了,已经等着我们去访问。问题出现了,我们可能“同时”需要单例对象,也就是多线程并发访问创建单例对象,这时候就需要控制一下了,因为单例对象只能创建一个,如果对创建方法不加控制,可能出现:A线程访问getObj()创建对象,还没来得及运行下面第九行的创建代码,cpu被B线程夺走,B也执行getObj()方法,并成功创建对象,cpu执行进程切换会记录断点,以便恢复后接着执行,所以A线程恢复运行后会接着执行第九行的创建代码,这时就产生了多个对象。为了防止以上情况的发生,我们可以控制线程对getObj()的访问情况,使它们一个个顺序执行,当A线程执行getObj()方法时,其他线程在一旁等着,如果reference指向为空就创建对象,反之直接返回,这样大家得到的对象就是第一次成功创建好的那个new Singleton(43)对象,这样就保证了对象的唯一性,满足了“单例”的要求。

 1 class Singleton{//可以用final修饰,也可以不用
 2     private int val;
 3     private static Singleton reference=null;
 4     private Singleton(int val){
 5         this.val=val;
 6     }
 7     synchronized public static Singleton getObj(){
 8         if(reference==null){
 9             reference=new Singleton(43);
10         }
11         return reference;
12     }
13     public void setVal(int val){
14         this.val=val;        
15     }
16     public int getVal(){
17         return this.val;        
18     }
19 }

注:以上内容是参看《Thinking in Patterns》后的总结结果,不足之处请大家多多指教。

原文地址:https://www.cnblogs.com/codeMedita/p/6910901.html