设计模式(一)单例模式

PupilYu    2019年03月28日


Java中稍微细分的话有七种单例模式,下面由简单到复杂,由缺陷到全面逐一介绍。

1.饿汉式

个人理解饿汉式的含义是饥饿难耐,上来就要“吃到东西”。代码如下:

/**
 * 饿汉式单例模式
 * 简单程度:★★★★★
 * 全面程度:★☆
 * 优点:代码简洁
 * 缺点:类加载时就初始化了对象
 */
public class Singleton1 {

    //私有化静态对象
    private static Singleton1 singleton1 = new Singleton1();

    //私有化构造方法
    private Singleton1() {
    }

    //获取实例方法
    public static Singleton1 getInstance() {
        return singleton1;
    }
}
2.懒汉式

懒汉式有懒加载的意思,使用时才加载。代码如下:

/**
 * 懒汉式单例模式
 * 简单程度:★★★★
 * 全面程度:★★
 * 优点:相较于饿汉式延迟了加载时机,第一次使用时才加载对象
 * 缺点:非线程安全
 */
public class Singleton2 {

    private static Singleton2 singleton2;

    private Singleton2() {
    }

    public static Singleton2 getInstance() {
        if (singleton2 == null) {
            singleton2 = new Singleton2();
        }
        return singleton2;
    }
}
3.同步锁式

同步锁式解决了线程安全问题,但又出现了效率问题。代码如下:

/**
 * 同步锁式单例模式
 * 简单程度:★★★☆
 * 全面程度:★★☆
 * 优点:相较于懒汉式保证了线程安全
 * 缺点:这种加锁方式导致效率下降
 */
public class Singleton3 {

    private static Singleton3 singleton3;

    private Singleton3() {
    }

    //获取实例的方法改成用 synchronized 修饰的同步方法
    public static synchronized Singleton3 getInstance() {
        if (singleton3 == null) {
            singleton3 = new Singleton3();
        }
        return singleton3;
    }
}
4.双重检测式

双重检测式为了提高效率,在代码简洁度上做了让步。代码如下:

/**
 * 双重检测式单例模式
 * 简单程度:★★★
 * 全面程度:★★★
 * 优点:相较于同步锁式仅在第一次获取时会加锁,效率有所提高
 * 缺点:双重判断,写法繁琐
 */
public class Singleton4 {

	//用 volatile 修饰,保证实例的状态对所有线程可见
    private static volatile Singleton4 singleton4;

    private Singleton4() {

    }

    public static Singleton4 getInstance() {
        if (singleton4 == null) {
            synchronized (Singleton4.class) {
                //如果同步代码块内部不再次判断非空,仍然会产生线程安全问题
                if (singleton4 == null) {
                    singleton4 = new Singleton4();
                }
            }
        }
        return singleton4;
    }
}
5.静态内部类式

代码如下,当任何一个线程第一次调用 getInstance() 时,都会使 Singleton5Holder 加载,也就是被调用时才进行初始化,Java机制保证了初始化静态数据时的线程安全性,所以不需要任何的同步措施。

/**
 * 静态内部类式单例模式
 * 简单程度:★★★★
 * 全面程度:★★★★
 * 优点:被调用时才初始化,同时保证线程安全性
 * 缺点:无
 */
public class Singleton5 {

    private Singleton5() {
    }

    private static class Singleton5Holder {
        private final static Singleton5 singleton5 = new Singleton5();
    }

    public static Singleton5 getInstance() {
        return Singleton5Holder.singleton5;
    }
}
6.枚举实现单例
/**
 * 枚举式单例模式
 * 简单程度:★★★★☆
 * 全面程度:★★★★★
 * 优点:保证线程安全,保证序列和反序列化情况下的单例
 * 缺点:无
 */
public enum Singleton6 {

    INSTANCE;

    //在枚举内部实现 enumSingleton 对象的单例
    private EnumSingleton enumSingleton;

    private Singleton6() {
        enumSingleton = new EnumSingleton();
    }

    public EnumSingleton getInstance() {
        return enumSingleton;
    }
}
public class EnumSingleton {
    //内部实现...
}
7.容器方式实现单例

用 HashMap 不能存放相同对象的特性来达到单例的效果,这里就不详细介绍了。
另外饿汉式还有一种变种,就是在静态代码块中初始化对象,其实无关紧要,也不详细说了。

其实对某些单例模式用到的底层机制并不了解,只知道这么用能保证单例,只是先在此记录一下。


参考:【单例深思】枚举实现单例原理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值