手写一个单例模式是 Java 面试中常见的问题,很多时候我们更偏向于简单的写一个饿汉或饱汉模式,深入研究的甚少,这里列举三种实现方式,并对各自的优缺进行分析。

1. 饿汉式

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

  这种方式要求类在加载时就要实例化,所以程序开始时就可能产生许多暂时没有不会用到的实例,减缓了程序初始化过程。但它写法简便,线程安全,是完成相关题目时的首选,同时这也是部分 IDE 工具在自动创建单例的时候默认采用的写法。

2. 饱汉式

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

  首次获取该类实例时才进行实例化,符合程序设计要求,同时结构还算清晰,一般也能准确编写。但这种实现方式本身线程不安全,需要用 synchronized 关键字做方法同步。

3.双重锁式

publc class Singleton {
private Singleton(){}
private volatile static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

  其实这种方式可以看作是饱汉模式的一种改进,主要考虑到同步是一种高开销的操作,应该尽量减少同步的内容,所以这里在获取实例的静态方法里面做了代码块同步,不再像之前,每次启用 getInstance 方法获取实例时,不管实例是否已经存在都会对后续操作进行同步处理。这里先对实例是否存在进行判断,当确实例不存在确实需要进行实例化操作时再做后续操作,而在入同步代码块前一刻始终有可能另一个线程已经对其完成了实例化,所以还要再做第二次判断,volatile 能保证各线程对 instance 进行操作时的可见性,即保证每次进行判断时 instance 的值都是最新的。

Java 代码编写单例模式总结的更多相关文章

  1. Java代码编写规范(不是标准规范,自行整理,无须纠结)

    最近回过头来给以前的项目增加功能,发现之前写的注释非常不全,代码也非常的不整洁,有些地方写的''窝七八烂的,看着很不舒服:又恰好经理最近也经常跟我提起代码规范,我们就讨论了一下代码规范的重要性和必要性 ...

  2. Java代码编写的一般性指导

    (1) 命名规则:这个最基本,也最重要,请牢记. 1,类名首字母应该大写. 2,字段.方法以及对象(句柄)的首字母应小写. 3,对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字 ...

  3. Java学习---Java代码编写规范

    编码规范 1 前言为确保系统源程序可读性,从而增强系统可维护性,java编程人员应具有基本类似的编程风格,兹制定下述Java编程规范,以规范系统Java部分编程.系统继承的其它资源中的源程序也应按此规 ...

  4. Java代码编写规范(转载)

    编码规范 1 前言为确保系统源程序可读性,从而增强系统可维护性,java编程人员应具有基本类似的编程风格,兹制定下述Java编程规范,以规范系统Java部分编程.系统继承的其它资源中的源程序也应按此规 ...

  5. Java代码编写、代码优化技巧总结

    随着工作经验的积累,在代码编写和优化方面,个人的心得体会总结以及有些从网上或书本中看到的有用技巧 1. 判断何时使用keySet()和entrySet() 获取Map 的key 和value 当循环中 ...

  6. Java代码编写的30条建议

    1) 类名首字母应该大写.字段.方法以及对象(句柄)的首字母应小写.对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母.例如: ThisIsAClassName thisIsM ...

  7. 大数据之路week07--day03(Hadoop深入理解,JAVA代码编写WordCount程序,以及扩展升级)

    什么是MapReduce 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃. MapReduce方法则是: 1.给在座的所有玩家中分配这摞牌 2.让每个玩家数自己手中的牌有几 ...

  8. 高质量JAVA代码编写规范

    1. Java 命名约定 除了以下几个特例之外,命名时应始终采用完整的英文描述符.此外,一般应采用小写字母,但类名.接口名以及任何非初始单词的第一个字母要大写. 1.1 一般概念 * 尽量使用完整的英 ...

  9. Java代码实现单例模式

    public class Single { /*private static final Single single=new Single(); private Single(){} public s ...

随机推荐

  1. soapUI与post测试soap webservice接口

    之前装了SoapUI,最近装了Postman,分别用它们测试了WebService,下面为用法. 测试的在线WebService(数据来源于中国气象局)Endpoint: http://www.web ...

  2. 一语道破Java 11的ZGC为何如此高效

    GC是大部分现代语言内置的特性,Java 11 新加入的ZGC号称可以达到10ms 以下的 GC 停顿,本文作者对这一新功能进行了深入解析.同时还对还对这一新功能带来的其他可能性做了展望.ZGC是否可 ...

  3. WCF Restful Service

    对 Web Services.WCF 和 Restful 的扫盲可参见:https://www.cnblogs.com/scy251147/p/3382436.html 关于之前对 WCF 的学习,可 ...

  4. Computer Vision_33_SIFT:TILDE: A Temporally Invariant Learned DEtector——2014

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...

  5. Nginx.conf配置文件默认配置块略解

    #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...

  6. C#预处理器指令——学习

    若要详细了解如何使用 C# 预处理器指令选择性地编译代码段,请参阅 #define(C# 参考)和 #if(C# 参考). #define(C# 参考) 地址:https://docs.microso ...

  7. sql网址

    w3school版 https://www.w3school.com.cn/sql/index.asp 菜鸟教程版 https://www.runoob.com/sql/sql-tutorial.ht ...

  8. flask中使用ajax 处理前端请求 弹框展示

    菜小鱼初次使用 ajax,想前端提交数据,后端处理后,将结果以弹框的形式展示,在网上查看了好多,不停的调试,终于调通了 html: <html> <head></head ...

  9. rsync详细解读

    本文通过示例详细分析rsync算法原理和rsync的工作流程,是对rsync官方技术报告和官方推荐文章的解释.本文不会介绍如何使用rsync命令(见rsync基本用法),而是详细解释它如何实现高效的增 ...

  10. python定义函数时的参数&调用函数时的传参

    一.定义函数: 1.位置参数:直接定义参数 2.默认参数(或者关键字参数):参数名 = "默认值" 3.位置参数必须在默认参数之前 二.调用函数: 1.按位置传,直接写参数的值 2 ...