单例模式总结

单例模式:一个类中,有且仅有一个对象,并提供有且仅有的一个全局访问方法。

 

场景:

 

①数据库对象,I/O操作对象

 

②工具类对象

 

③全局共享的数据(Android中的MyApplication ,全局共享的数据等)

 

 

 

结构图如下:

 

Singleton

- instance:Singleton

- Singleton()

+ getInstance()

 

 

【1】饿汉模式(一来就直接创建对象,无论是否使用)

public class Singleton{

      public static Singleton singleton = new Singleton();
     
       private Singleton(){
       }
  
      public static Singleton getInstance(){
	   return singleton;
       }

}

特点:

 

①类加载时就完成了初始化(静态声明);

 

②基于类的加载机制,避免了多线程同步问题;

 

③类加载速度较慢,但获取对象的速度较快;

 

④如果一直没有使用,则会浪费资源。

 

■通俗理解:提前给了钱订了位置,但来不来用就是一码事,不来用就浪费资源

 

 

 

 

【2】懒汉模式(要用的时候才创建对象)

⑴线性不安全:

//线性不安全
public class Singleton{
    private static Singleton singleton ;
    private Singleton(){//此处将无参数的构造函数声明为私有,外部就无法重写,防止多个实例的产生
    }
    public static Singleton getInstance(){
        if(singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
}

特点:

 

①第一次调用才初始化,节省了资源;

②正是由于第一次调用才产生实例,所以第一次调用相对较慢,后续则较快;

 

 

 

⑵线性安全:

//线性安全
public class Singleton{
    
       private static Singleton singleton = null;
	
        private Singleton{
	}
  
       public static synchronized Singleton getInstance(){//注意此处使用了synchronized声明为同步
          if(singleton == null){
		singleton = new Singleton();
	   }
      
         return singleton;
        }
 }

特点:

 

①第一次调用才初始化,节省了资源;

②正是由于第一次调用才产生实例,所以第一次调用相对较慢,后续则较快;

③由于使用了同步关键字,所以在多线程中是线性安全的;

④每次调用都需要同步一下,会造成一定的同步开销;

■通俗理解:上车买票,第一次上车时买了车票,以后每次到一个站上一次厕所回来再上车只是检查一下车票,但不用再买票

 

 

 

 

 

【3】双重检查锁定(double-checked locking:缩写DCL)模式(要用的时候才创建对象)

public class Singleton_dcl {
    
    private volatile static Singleton_dcl singleton_dcl;
    private Singleton_dcl(){
    }
    
    public static Singleton_dcl getInstance(){
        if(singleton_dcl == null){//如果不为空,则跳过,避免每次都需要同步都消耗资源
            synchronized (Singleton_dcl.class){
                if(singleton_dcl == null){
                    singleton_dcl = new Singleton_dcl();
                }
            }
        }
        return singleton_dcl;
    }
    
}

特点:

 

①第一次加载时才实例化单例对象,但第一次加载速度较慢

 

②避免每次调用都同步,省去多余的同步,节省资源消耗

 

③在高并发的情况下会有一定问题。

 

■通俗理解:上车买票,第一次上车时买票,会通过系统进行处理,后面每次停站从厕所回来,上车时乘务员就检查一下车票就行,不需要输入车票信息去查系统去同步查看

注意:双重检查锁定模式不适用1.4及更早版本的JAVA,因为许多JVM对于volatile的实现会导致该模式失效

 

 

 

 

 

【4】静态内部类单例模式

public class Singleton_innerCls {

    private Singleton_innerCls(){}

    private static class SingletonHolder{//内部类
        private static final Singleton_innerCls mInstance = new Singleton_innerCls();
    }

    public static Singleton_innerCls getInstance(){
        return SingletonHolder.mInstance;
    }

}

特点:

 

①第一次加载类时不会初始化对象

 

②第一次调用getInstance()时,虚拟机加载静态内部类SingletonHolder,并且初始化对象

 

③可以确保线程安全

 

 

 

 

★总结:

 

①所有模式当中,有且仅有一个公共方法,就是获取对象的方法getInstance();

 

②其余的方法、常量、内部类统统都声明为私有private,特别要注意默认的构造方法必须要声明为私有

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值