面试官:请你手搓单例模式,并给出优化设计

0 饿汉式

  • 好处:类加载到内存后,JVM 保证了线程安全(只会加载到内存一次)

  • 坏处:不管用到与否,类加载的时候就完成了实例化

public class SingletonDemo{
public static final SingletonDemo INSTANCE = new SingletonDemo();

// 私有化的空参构造(保证除了本类,其他类无法 new 这个类的对象)
private SingletonDemo(){

}

public static SingletonDemo getInstance(){
return INSTANCE;
}
}


1 懒汉式

  • 加锁,但是效率比较低

public class SingletonDemo{
public static SingletonDemo INSTANCE;

// 私有化的空参构造(保证除了本类,其他类无法 new 这个类的对象)
private SingletonDemo(){

}

public static synchronized SingletonDemo getInstance(){
if(INSTANCE == null){
INSTANCE = new SingletonDemo();
}
return INSTANCE;
}
}


  • 双重校验

public class SingletonDemo{
// 要加上 volatile 禁止指令重排,否则会有问题
public static volatile SingletonDemo INSTANCE;

// 私有化的空参构造(保证除了本类,其他类无法 new 这个类的对象)
private SingletonDemo(){

}

public static SingletonDemo getInstance(){
if(INSTANCE == null){
// 双重检查
synchronized(SingletonDemo.class){
if(INSTANCE == null){
INSTANCE = new SingletonDemo();
}
}
}
return INSTANCE;
}
}


  • 优化,改为静态内部类的方式(推荐)

    • 注意:只加载 SingletonDemo 的话,SingletonDemoHolder 是不会被加载的(只有当调了 getInstance() 方法的时候静态内部类才会被加载)

    • 线程安全也是 JVM 保证的

    • 也保证了懒加载

public class SingletonDemo{

// 私有化的空参构造(保证除了本类,其他类无法 new 这个类的对象)
private SingletonDemo(){

}

private static class SingletonDemoHolder{
private static final INSTANCE = new SingletonDemo();
}

public static SingletonDemo getInstance(){
return SingletonDemoHolder.INSTANCE;
}
}


  • 进一步优化,枚举类 –>《JavaEffective》里的推荐写法

    • 保证线程同步、还可以防止反序列化(因为 Java 规范中规定,每一个枚举类型极其定义的枚举变量在 JVM 中都是唯一的,因此在序列化和反序列化之后 serialVersionUID 都是同一个)

public enum SingletonDemo{
INSTANCE;
public SingletonDemo getInstance(){
return INSTANCE;
}
}


  • 设计模式之单例模式 就到此为止啦,如有错误,欢迎指正。

  • 创作不易,感谢阅读,若遇到问题,可以关注此微信公众号留言反馈,希望能够帮助到您。


原文始发于微信公众号(EzCoding):面试官:请你手搓单例模式,并给出优化设计

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/203645.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!