博客
关于我
单例模式的几种实现
阅读量:453 次
发布时间:2019-03-06

本文共 2061 字,大约阅读时间需要 6 分钟。

  简单点说,就是一个应用程序中,某个类的实例对象只有一个,你没有办法去new,因为构造器是被private修饰的,一般通过getInstance()的方法来获取它们的实例。getInstance()的返回值是一个对象的引用,并不是一个新的实例,所以不要错误的理解成多个对象。单例模式实现起来也很容易,直接看demo吧

 懒汉式写法(线程不安全)

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 instance;     private Singleton (){}     public static synchronized Singleton getInstance() {     if (instance == null) {         instance = new Singleton();     }     return instance;     }  }

 

饿汉式写法

 线程安全,比较常用,但容易产生垃圾,因为一开始就初始化

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

静态内部类

public class Singleton {     private static class SingletonHolder {       private static final Singleton INSTANCE = new Singleton();     }     private Singleton (){}     public static final Singleton getInstance() {       return SingletonHolder.INSTANCE;     }  }
只有第一次调用getInstance方法时,虚拟机才加载 SingletonHolder并初始化INSTANCE,只有一个线程可以获得对象的初始化锁,其他线程无法进行初始化,保证对象的唯一性。目前此方式是所有单例模式中最推荐的模式,但具体还是根据项目选择。

 枚举

public enum Singleton {     INSTANCE;     public void whateverMethod() {     }  }

这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒啊,不过,个人认为由于1.5中才加入enum特性,用这种方式写不免让人感觉生疏。

双重校验锁

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;     }  }

线程安全,延迟初始化。这种方式采用双锁机制,安全且在多线程情况下能保持高性能

总结:我个人比较喜欢静态内部类写法和饿汉式写法,其实这两种写法能够应付绝大多数情况了。其他写法也可以选择,主要还是看业务需求吧。

转载地址:http://xsdbz.baihongyu.com/

你可能感兴趣的文章
JavaScript中事件处理
查看>>
前端自动化构建工具gulp记录
查看>>
Hammer.js分析(四)——recognizer.js
查看>>
综合架构的简述
查看>>
经典shell面试题
查看>>
Linux基础命令总结
查看>>
CentOS 7 Xinetd服务安装配置
查看>>
2019年8月19日~8月25日 第八周JAVA学习总结
查看>>
13.罗马数字转整数
查看>>
Java中Runtime类详细总结
查看>>
JSP中引用CSS样式文件却无法显示的问题解决方案
查看>>
WPF 新突破
查看>>
网站状态码
查看>>
数据库优化
查看>>
elasticsearch安装01
查看>>
[备忘]21个演示展示强大的jQuery特效
查看>>
[备忘]域用户登陆出现“此工作站和主域间的信任关系失败”错误解决方法
查看>>
stout代码分析之二:None类
查看>>
hadoop压缩和解压
查看>>
Hyper和Vmware冲突,Device/Credential Guard 不兼容
查看>>