单例设计模式(Singleton)8种写法及各种写法的优劣分析

单例设计模式

1. 什么是单例设计模式:
保证一个类在项目中只有一个实例,并提供访问他的方法。

2. 为什么要用单例设计模式:
对于一些类来说,只有一个实例很重要,如一个会计系统只能专用于一个公司。

3. 单例设计模式适用于什么地方:
------当类只能有一个实例而且客户可以从一个众所周知的访问点访问他时。
------这个唯一实例时通过子类化科扩展的,并且客户端应该无需更改代码就能使用一个扩展实例时。
------需要频繁的创建和销毁对象的时候。

单例设计模式的设计思路:

  1. 为了防止被外界直接new出,需要重写单例类的空构造方法,并把这个方法私有化。
  2. 类的内部创建对象。
  3. 提供一个对外的接口,使需要的地方能通过这个接口获取。

以下使单例模式8种实现案例:

1. 饿汉式实现:
class singletonFirst {

    //1、提供私有空构造方法,使外界无法new出
    private singletonFirst() { };

    //2、在内部实例被单例的类
    private final static singletonFirst instance = new singletonFirst();

    //3、对外提供访问接口
    public static singletonFirst getInstance() {
        return instance;
    }
}

优势:

  • 写法较为简单,类加载时完成实例化,避免了线程同步问题。

劣势:

  • 类装载时就完成实例化,可能出现从始至终都没用过这个类的情况,而却创造了这个类的实例,对内存资源造成浪费。

推荐等级:可用,但会造成资源浪费

2、饿汉式静态代码块实现:
class SingletonSecond{
    //1、提供私有空构造方法,使外界无法new出
    private SingletonSecond() { };

    //2、在内部实例被单例的类
    private final static SingletonSecond instance;

    static {
        instance =  new SingletonSecond();
    }

    //3、对外提供访问接口
    public static SingletonSecond getInstance() {
       return instance;
    }

}

优点与缺点:

与上一个方法类似,只是将类实例化放到静态代码块中,优缺点和上面相同

推荐等级:可用,但会造成资源浪费

3、懒汉式实现(线程不安全):
class SingletonThird{

    private SingletonThird(){};

    private static  SingletonThird singletonThird;

    public static SingletonThird getInstance(){
        if(singletonThird==null){
        
            singletonThird = new SingletonThird();   
        }
        return singletonThird;
    }
}

优点:

  • 有懒加载效果,但只能用于单线程。

缺点:

  • 在多线程下,如果一个线程进入if判断语句,另一个线程也进入该语句,则可能造成多个实例。

推荐:实际开发中,不要使用这种方式

4、懒汉式实现(线程安全):
class SingletonFourth{
    private SingletonFourth(){};

    private static  SingletonFourth singletonFourth;

    public synchronized static  SingletonFourth getInstance(){
        if(singletonFourth==null){
            singletonFourth = new SingletonFourth();
        }
        return singletonFourth;
    }
}

优点:

  • 实现了懒加载及线程安全

缺点:

  • 效率太低,调用方法要等待锁的释放。

推荐:实际开发中,不推荐使用这种方式

5、懒汉式实现(线程安全,同步代码块):
class SingletonFive{
    private SingletonFive(){};
    
    private static  SingletonFive singletonFive;

    public  static  SingletonFive getInstance(){

        if(singletonFive==null){
            synchronized (SingletonFive.class){
                singletonFive = new SingletonFive();
            }
        }
        return singletonFive;
    }
}

优点:

  • 有同步代码块,也能有较快的解决速率。

缺点:

  • 假如有2个线程同时进入if语句,则会创建不同的对象。

推荐:实际开发中,不能使用这种方式

6、双重检索:
class SingletonSix{

    private SingletonSix(){};

    private static  SingletonSix singletonSix;

    public  static  SingletonSix getInstance(){

        if(singletonSix==null){
            synchronized (SingletonSix.class){
                if(singletonSix==null) {
                    singletonSix = new SingletonSix();
                }
            }
        }
        return singletonSix;
    }
}

优点:

  • 既能解决线程同步问题,又能有较快的效率,也能实现懒加载。

缺点:

  • 无。

推荐:实际开发中,推荐使用这种方式

7、静态内部类实现:
class SingletonSeven{

    private SingletonSeven(){};


    private static  class SingeltonInstance{
        private static final SingletonSeven instance = new SingletonSeven();
    }

    public static SingletonSeven getInstance(){

        return SingeltonInstance.instance;
    }
    
}

优点:

  • 采用类加载机制保证初始化实例只有一个进程。
  • 静态内部类在单例类实例化时不会立即实例化,而是需要实例时调用getInstance方法装载内部类,完成单例类实例。
  • 避免了线程不安全,利用静态内部类特点实现延迟加载,效率高。

缺点:

  • 无。

推荐:实际开发中,推荐使用这种方式

8、枚举实现:
public class SingletonTestEight {
    public static void main(String[] args) {
        Singleton singleton = Singleton.INSTANCE;
        singleton.say();
    }
}

enum Singleton{
   INSTANCE;
   public void say(){

   }

}

优点:

  • 借助JDK1.5中的枚举来实现单例模式,能避免多线程安全问题,还能防止序列化重新创建新的对象。

推荐:实际开发中,推荐使用这种方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值