什么是单例模式

世界上没有两片完全相同的树叶,每一个物体都是唯一的。所谓单例就是唯一份,在java中来说就是 实例化只是执行一次,也可以理解为对象只new一次。

单例模式的代码实现

接下来就是我们的单例模式写法推荐排行榜:

第八名懒汉式(线程不安全) 推荐指数:

懒汉式(线程不安全)写法起到了Lazy Loading的效果,但是只能在单线程下使用。如果在多线程下,一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以在多线程环境下不可使用这种方式。

package cn.zhuoqianmingyue.examples.singletonpattern;public class SlackerManSingletonFirst {private static SlackerManSingletonFirst instance = null;private SlackerManSingletonFirst() {};public static SlackerManSingletonFirst getInstance() {if(instance == null) {instance = new SlackerManSingletonFirst();}return instance;}public static void main(String[] args) {SlackerManSingletonFirst instance1 = SlackerManSingletonFirst.getInstance();SlackerManSingletonFirst instance2 = SlackerManSingletonFirst.getInstance();System.out.println(instance1 == instance2);}
}

第七名懒汉式(线程安全,同步代码块) 推荐指数

第六名 懒汉式(线程安全,同步方法)方式同步效率太低,所以摒弃同步方法,改为同步产生实例化的的代码块。但是这种同步并不能起到线程同步的作用。跟第3种实现方式遇到的情形一致,假如一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。

package cn.zhuoqianmingyue.examples.singletonpattern;public class SlackerManSingletonThird {private static SlackerManSingletonThird instance = null;private SlackerManSingletonThird() {}public static SlackerManSingletonThird getInstance() {if (instance == null) {synchronized (SlackerManSingletonThird.class) {instance = new SlackerManSingletonThird();}}return instance;}public static void main(String[] args) {SlackerManSingletonThird instance1 = SlackerManSingletonThird.getInstance();SlackerManSingletonThird instance2 = SlackerManSingletonThird.getInstance();System.out.println(instance1 = instance2);}
}

第六名 懒汉式(线程安全,同步方法)推荐指数

解决线程不安全问题,对getInstance()方法进行了线程同步。

缺点:效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低要改进。

package cn.zhuoqianmingyue.examples.singletonpattern;public class SlackerManSingletonSecond {private static SlackerManSingletonSecond instance = null;private SlackerManSingletonSecond() {}public static synchronized SlackerManSingletonSecond getInstance() {if (instance == null) {instance = new SlackerManSingletonSecond();}return instance;}public static void main(String[] args) {SlackerManSingletonSecond instance1 = SlackerManSingletonSecond.getInstance();SlackerManSingletonSecond instance2 = SlackerManSingletonSecond.getInstance();System.out.println(instance1 == instance2);}
}

第五名 饿汉式(静态常量)推荐指数

优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。

package cn.zhuoqianmingyue.examples.singletonpattern;public class SingletonFirst {private final static SingletonFirst INSTANCE = new SingletonFirst();private SingletonFirst() {}public static SingletonFirst getInstance() {return INSTANCE;}public static void main(String[] args) {SingletonFirst instance1 = SingletonFirst.getInstance();SingletonFirst instance2 = SingletonFirst.getInstance();System.out.println(instance1 == instance2);}
}

第四名 饿汉式(静态代码块)推荐指数

这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。优缺点和上面是一样的。

package cn.zhuoqianmingyue.examples.singletonpattern;public class HungryManSingletonSecond {private static HungryManSingletonSecond instance;static {instance = new HungryManSingletonSecond();}public static  HungryManSingletonSecond getInstance() {return instance;}public static void main(String[] args) {HungryManSingletonSecond instance1 = HungryManSingletonSecond.getInstance();HungryManSingletonSecond instance2 = HungryManSingletonSecond.getInstance();System.out.println(instance1 == instance2);}
}

第三名 双重检查 推荐指数

Double-Check概念对于多线程开发者来说不会陌生,如代码中所示,我们进行了两次if (singleton == null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if (singleton == null),直接return实例化对象。

优点:线程安全;延迟加载;效率较高。

package cn.zhuoqianmingyue.examples.singletonpattern;public class SlackerManSingletonFourth {private static SlackerManSingletonFourth instance = null;private SlackerManSingletonFourth() {}public static SlackerManSingletonFourth getInstance() {if (instance == null) {synchronized (SlackerManSingletonFourth.class) {if (instance == null) {instance = new SlackerManSingletonFourth();}}}return instance;}public static void main(String[] args) {SlackerManSingletonFourth instance1 = SlackerManSingletonFourth.getInstance();SlackerManSingletonFourth instance2 = SlackerManSingletonFourth.getInstance();System.out.println(instance1 == instance2);}
}

第二名 静态内部类 推荐指数

这种方式跟饿汉式方式采用的机制类似,但又有不同。两者都是采用了类装载的机制来保证初始化实例时只有一个线程。不同的地方在饿汉式方式是只要Singleton类被装载就会实例化,没有Lazy-Loading的作用,而静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的实例化。

类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。

优点:避免了线程不安全,延迟加载,效率高。

package cn.zhuoqianmingyue.examples.singletonpattern;public class InnerClassSingleton {private InnerClassSingleton() {}private static class SingletonInstance {private static final InnerClassSingleton INSTANCE = new InnerClassSingleton();}public static InnerClassSingleton getInstance() {return SingletonInstance.INSTANCE;}public static void main(String[] args) {InnerClassSingleton instance1 = InnerClassSingleton.getInstance();InnerClassSingleton instance2 = InnerClassSingleton.getInstance();System.out.println(instance1 == instance2);}
}

第一名 枚举 推荐指数

借助JDK1.5中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。可能是因为枚举在JDK1.5中才添加,并且是官方推荐使用。

package cn.zhuoqianmingyue.examples.singletonpattern;public enum EnumSingleton {INSTANCE;public static void main(String[] args) {EnumSingleton instance1 = EnumSingleton.INSTANCE;EnumSingleton instance2 = EnumSingleton.INSTANCE;System.out.println(instance1 == instance2);}
}

代码例子和优缺点内容来源:https://www.cnblogs.com/zhaoyan001/p/6365064.html 自己对代码做了简单修改的同时搞了个排名。有点借花献佛的意思,还望原作者谅解。
参考文献 https://www.cnblogs.com/zhaoyan001/p/6365064.html

1小时搞懂设计模式之单例模式相关推荐

  1. 1小时搞懂设计模式之工厂模式(方法工厂)

    1 简单工厂缺点 以及方法工厂实现逻辑 通过我的上一篇博客 工厂模式之简单工厂 我们了解了什么是简单工厂.我们可以通过创建钢工厂类对象来获取不同类型的钢对象.但是如果我们每次新增加一种类型的钢,我们需 ...

  2. 1小时搞懂设计模式之原型模式

    1 什么是原型模式 原型模式根据一个对象在重新创建一个对象 并保证这2个对象内容是一致的.java中的克隆技术就是原型模式的实现. 2 原型模式的特点 有一个可以被拷贝的原型对象 保证被拷贝的对象和原 ...

  3. 1小时搞懂设计模式之委派模式

    1 什么是委派模式 委派模式 我们可以理解成上级分配任务到具体的员工,比如说您是一个大老板 手下有上千个员工,平常端茶递水的活肯定不是自己干.一般口渴了 就会跟下面经理说:小张啊 我口渴了给我倒点茶! ...

  4. 1小时搞懂设计模式之策略模式

    1 什么是策略模式 简单一句话理解就是通过不同的方式来完成一件事.我们拿生活举例:年终将至又到了涨工资的时候了,领导会根据你今年工作表现来将员工分为三种: 工作不积极的坏员工 对于坏员工执行不涨薪策略 ...

  5. 1小时搞懂设计模式之工厂模式(简单工厂)

    1 什么是工厂模式 一说到工厂你有可能会想到 食品加工厂,汽车工厂,钢厂等. 这些工厂能帮我们干什么呢? 比如:食品加工厂帮我们生产 面包 饼干,汽车工厂帮我们生产汽车 .钢厂能帮我们生产钢.诸如这些 ...

  6. 1小时搞懂设计模式之代理模式(静态代理)

    1 什么是代理模式 这个问题让我们用生活的例子来进行解释,在我们买火车票的时候可以通过黄牛帮我们买票 ,或者 我们通过媒婆介绍对象找到我们生活中的另一伴.在或者每个明星需要经纪人帮忙打理他的通告.这些 ...

  7. 一篇博客读懂设计模式之---单例模式

    一篇博客读懂设计模式之---单例模式 一.  单例模式 单例对象(Singleton)是一种常用的设计模式.在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在.这样的模式有几个好处 ...

  8. 一文搞懂设计模式--模板模式

    Hi,大家好.今年的天气实在是太热了,七月份的厦门晒得我觉得身上冒出了烤肉香,不知道各位是否安好,但是在再热的天气也不能阻止我们学习的热情(doge).今天的主题是模板(Template Method ...

  9. 一文让你搞懂设计模式

    最近在研究设计模式,发现尽管设计模式是针对面向对象语言提出的,但貌似市面上大多数都是基于java给出的例子,C++的例子极少,自己看完李建忠老师的GOF设计模式视频后查阅各种资料后,把主要的设计模式用 ...

最新文章

  1. SUST_ACM_2019届暑期ACM集训热身赛题解
  2. atoi() //把字符串转换成整型数
  3. python输入文字、成为字典_Python 字典(Dictionary)操作详解
  4. 【2012百度之星/资格赛】E:C++ 与Java
  5. C#基础加强(8)之委托和事件
  6. React开发(254):react项目理解 ant design 注意参数传递格式
  7. 专访世界顶级游戏背后的男人
  8. 【bzoj2330】 [SCOI2011]糖果
  9. Cmake-add_library()
  10. 30岁学python有前途吗-30岁新手入门python!尝试人生另一种可能
  11. protoc安装配置
  12. DSTE经营分析会(战略落地的核心抓手)
  13. wordpress博客引用外链图片加载不出
  14. 密码学的安全性浅析-3
  15. 5分钟读懂UML类图
  16. 理解GBASE LDAP认证方法
  17. 梅森数形如2n−1的素数称为梅森数(Mersenne Number)
  18. 一文弄懂JVM内存结构,垃圾回收器和垃圾回收算法
  19. Windows10 Emacs-SML开发环境搭建
  20. mysql stdistance_SQL Server 利用 geography 计算地理位置距离、距我最近排序

热门文章

  1. java test20006_java 数组 (数组个数小于2000)
  2. java 代码块同步,Java 同步代码块
  3. [专栏精选]Unity中动态构建NavMesh
  4. OpenShift 4 Hands-on Lab (1) - 多种方法部署运行应用
  5. Microsoft Blazor——动态内容
  6. Microsoft Edge 83 稳定版发布
  7. Python教程和PyMySQL数据库导航
  8. 大工18春计算机文化基础在线测试1,大工18春《计算机文化基础》在线测试1(满分答案)...
  9. spring boot注解_Spring-boot(二)注解
  10. qt判断读入的字符串是否含有英文_重复的子字符串