单例模式/ java实现附代码 /

注: 场景和例子出自github的设计模式。传送门:https://github.com/iluwatar/java-design-patterns/tree/master/singleton

意图:

        单例模式即使为了确保一个类只有一个实例,并提供一个全局访问点。

场景:

        世界上只有一座象牙塔可以让巫师学习魔法,所有巫师都来到这座象牙塔进行修习。那么象牙塔就这里可以理解为单例。简单的来说就是只创建一个类的一个对象,这个象牙塔就可以理解为唯一对象。

实现:

        想更好的理解单例模式,最好先了解一下java中的关键字Static。传送门:http://www.cnblogs.com/ahangBlogs/p/7719330.html

talk is cheap,show me the code.........................................................................................................................................................................................................................................(分割线)

 

列举几种单例模式的实现方法:

 一:

package Singleton;

public final class IvoryTower {
     private IvoryTower(){}
     
     private static final IvoryTower Instance=new IvoryTower();
     
     public static IvoryTower GetInstance(){
         return Instance;
     }
}

二:ThreadSafeLazyLoaded

package Singleton;
public final class ThreadSafeLazyLoadedIvoryTower {
      private static ThreadSafeLazyLoadedIvoryTower Instance;
      
      private ThreadSafeLazyLoadedIvoryTower(){
          if(Instance!=null){
              throw new IllegalStateException("Already initialized.");
          }
      }      
      public static ThreadSafeLazyLoadedIvoryTower GetInstance(){
          if(Instance==null){
              Instance=new ThreadSafeLazyLoadedIvoryTower();
          }
          return Instance;
      }
}

三:线程安全双重锁检查

package Singleton;
public class ThreadSafeDoubleCheckLocking {
       private static ThreadSafeDoubleCheckLocking instance;
       
       private ThreadSafeDoubleCheckLocking(){
           if(instance!=null){
               throw new IllegalStateException("Already instance!");
           }
       }
       
       public static ThreadSafeDoubleCheckLocking GetInstance(){
           //使用局部变量可提高25%性能。 出自effectice java th2.. 简单来说就是局部变量保存在堆栈中....
           ThreadSafeDoubleCheckLocking result=instance;
           
           //检查单例模式的实力是否初始化,如果已经初始化就直接返回实例,没有初始化就往下走
           if(result==null){
               //实例没有初始化,不过我们不能确保在这个时间段其他线程是否初始化了这个实例, 所以为了确保正确我们得锁住一个对象来互相排斥。             
               synchronized (ThreadSafeDoubleCheckLocking.class) {
                   //再次将是实例赋值给局部变量,这时候当前线程无法进入该锁空间,如果已经初始化我们返还实例
                   result=instance;
                   
                   if(result==null){
                       //进入该if中,即没有在其他线程中进行初始化。那么我们可以安全的创建一个实例作为我们的单例实例。
                       instance=result=new ThreadSafeDoubleCheckLocking();
                   }
            }              
           }
               return result;
       }
       
}

四:

package Singleton;

public enum EnumIvoryTower {
     INSTANCE;
    
     @Override
     public String toString(){
         return getDeclaringClass().getCanonicalName() + "@" + hashCode();
     }
}

适用性:

使用Singleton模式

  • 必须只有一个类的实例,并且必须可以从知名访问点访问客户端
  • 当唯一的实例应该通过子类来扩展时,客户端应该能够使用扩展实例而不修改它们的代

缺点:

  • 违反单一责任原则(SRP)通过控制自己的创作和生命周期。
  • 鼓励使用全局共享实例,以防止该对象使用的对象和资源被释放。
  • 创建紧密耦合的代码。Singleton的客户变得难以测试。

 

 

 

 

 

 

 

posted @ 2017-12-16 19:27  阿行不太冷  阅读(1538)  评论(0编辑  收藏  举报