Java设计模式——单例模式

一、概念

        单例模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。

二、常用写法

1.饿汉模式

  • 线程安全
  • 不需要Lazy初始化
  • 描述:容易产生垃圾对象
  • 优点:没有锁,执行效率高
  • 缺点:类加载时就初始化,浪费内存--容易产生垃圾对象
public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
        return instance;  
    }  
}

2.懒汉模式

  • 线程安全
  • Lazy初始化
  • 描述:能够再多线程中很好的工作,但效率很低;99%的情况下不需要同步
  • 优点:第一次调用才初始化,避免内存浪费
  • 缺点:必须加synchronized锁,保证单例,但加锁会影响效率。
public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static synchronized Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

3.双重检测机制(DCL)

  • 线程安全
  • 需要Lazy初始化
  • 描述:采用双锁机制,保证安全性,且在多线程情况下仍能够保持高性能
  • 缺点:实现难度较大
public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
        if (singleton == null) {  
            synchronized (Singleton.class) {  
                if (singleton == null) {  
                    singleton = new Singleton();  
                }  
            }  
        }  
        return singleton;  
    }  
}

4.静态内部类

  • 线程安全

  • 需要Lazy初始化
  • 描述:JVM将推迟SingletonHolder的初始化操作,直到开始使用这个类时才初始化,并且由于通过一个静态初始化来初始化Singleton,因此不需要额外的同步。当任何一个线程第一次调用getInstance时,都会使SingletonHolder被加载和被初始化,此时静态初始化器将执行Singleton的初始化操作。
public class Singleton {  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
    }  
}

5.枚举

  • 线程安全
  • 不是Lazy初始化
  • 描述:它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。不过,由于 JDK1.5 之后才加入 enum 特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少用。
public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {}  
}

三、单例模式实现方式对比

方式优点缺点
懒汉模式线程安全、懒加载非懒加载
饿汉模式线程安全、效率高效率低
双重检测(DCL)线程安全、懒加载、效率高实现难度较高
静态内部类线程安全、懒加载、效率高实现难度一般
枚举线程安全、效率高非懒加载

四、使用情况(经验之说)

        在面试的时候,建议使用双检锁的方式,进而引出synchronized锁!!!其他情况下:不建议使用懒汉方式,可以使用饿汉方式。明确懒加载效果时,建议使用静态内部类。如果涉及到反序列化创建对象时,可以使用枚举的方式。其它需求的情况下,可以使用双检锁方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值