Java 实现一个单例模式_Java实现单例模式的两种方式

Java 实现一个单例模式_Java实现单例模式的两种方式单例模式在实际开发中有很多的用途,比如我们在项目中常用的工具类,数据库等资源的连接类。这样做的好处是避免创建多个对象,占用内存资源,自始自终在内存中只有一个对象为我们服务。单例对象一般有两种实现方式。懒汉式和饿汉式。饿汉式实现如下:packagecom.day05;/***饿汉式**@authorAdministrator**/publicclassSingle{//定义一个个私有静态本类对…

大家好,又见面了,我是你们的朋友全栈君。

单例模式在实际开发中有很多的用途,比如我们在项目中常用的工具类,数据库等资源的连接类。这样做的好处是避免创建多个对象,占用内存资源,自始自终在内存中只有一个对象为我们服务。

单例对象一般有两种实现方式。懒汉式和饿汉式。

饿汉式实现如下:

packagecom.day05;/*** 饿汉式

*

*@authorAdministrator

**/

public classSingle {//定义一个个私有静态本类对象变量,饿汉式是一上来就给该变量进行初始化,加上final是让s这个对象引用始终保持不变,更为严谨

private static final Single s = newSingle();//构造方法私有化,让外部无法通过new 关键字来进行创建对象

privateSingle() {

}//暴露出一个外界可以获取该类对象的公共静态方法

public staticSingle getInstance() {returns;

}

}

测试类:

packagecom.day05;public classSingleDemo {public static voidmain(String[] args) {

Single s1=Single.getInstance();

Single s2=Single.getInstance();

System.out.println(s1==s2);

}

}

运行结果:

true

即s1==s2说明了,s1和s2在内存中地址都相等,即s1、和s2是同一个对象。

懒汉式实现如下:

packagecom.day05;/*** 懒汉式

*

*@authorAdministrator

**/

public classSingle {//定义一个个私有静态本类对象变量,懒汉式是先赋值为null,当需要的时候在初始化

private static Single s = null;//构造方法私有化,让外部无法通过new 关键字来进行创建对象

privateSingle() {

}//暴露出一个外界可以获取该类对象的公共静态方法

public staticSingle getInstance() {if (s == null)

s= newSingle();returns;

}

}

以上的代码如果是单线程的话就不会存在问题,但是当有多线程操作的时候,就会存在线程安全问题,演示代码如下:

packagecom.day05;/*** 懒汉式

*

*@authorAdministrator

**/

public classSingle {//定义一个个私有静态本类对象变量,懒汉式是先赋值为null,当需要的时候在初始化

private static Single s = null;//构造方法私有化,让外部无法通过new 关键字来进行创建对象

privateSingle() {

}//暴露出一个外界可以获取该类对象的公共静态方法

public staticSingle getInstance() {if (s == null) {try{

Thread.sleep(1000L);

}catch(InterruptedException e) {

e.printStackTrace();

}

s= newSingle();

}returns;

}

}

测试类如下:

packagecom.day05;public class SingleDemo implementsRunnable {public static voidmain(String[] args) {

SingleDemo sd= newSingleDemo();newThread(sd).start();newThread(sd).start();

}

@Overridepublic voidrun() {

Single s=Single.getInstance();

System.out.println(s);

}

}

运行结果如下:

com.day05.Single@4081b5a4

com.day05.Single@64dcdaac

可以发现每次运行结果打印出获取对象不是同一个,即存在线程安全问题。

问题分析:

67d0283fdb9526eb0f12a5d0788997a0.png

由此我们可以采用Java给我们提供的同步锁来解决以上的问题,修改代码如下:

packagecom.day05;/*** 懒汉式

*

*@authorAdministrator

**/

public classSingle {//定义一个个私有静态本类对象变量,懒汉式是先赋值为null,当需要的时候在初始化

private static Single s = null;//构造方法私有化,让外部无法通过new 关键字来进行创建对象

privateSingle() {

}//暴露出一个外界可以获取该类对象的公共静态方法

public static synchronizedSingle getInstance() {if (s == null) {try{

Thread.sleep(1000L);

}catch(InterruptedException e) {

e.printStackTrace();

}

s= newSingle();

}returns;

}

}

这样就解决了上面的代码存在的线程安全问题,但是同步锁虽然可以解决了线程安全问题,但是却会存在效率问题,所以我们可以采用双重判断的方法来优化一下改代码如下所示:

packagecom.day05;/*** 懒汉式

*

*@authorAdministrator

**/

public classSingle {//定义一个个私有静态本类对象变量,懒汉式是先赋值为null,当需要的时候在初始化

private static Single s = null;//构造方法私有化,让外部无法通过new 关键字来进行创建对象

privateSingle() {

}//暴露出一个外界可以获取该类对象的公共静态方法//这里需要注意的使静态共享数据使用的使该类的字节码对象即Single.class

public staticSingle getInstance() {//这里增加了一次判断,可以少一次进行锁的处理

if (s == null) {synchronized (Single.class) {if (s == null) {try{

Thread.sleep(1000L);

}catch(InterruptedException e) {

e.printStackTrace();

}

s= newSingle();

}

}

}returns;

}

}

总结:还是比较推荐使用饿汉式,因为写法简单,不存在线程安全问题。

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/156950.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • Nginx+DNS负载均衡「建议收藏」

    Nginx+DNS负载均衡「建议收藏」今天看了很多关于nginx负载均衡的博客,人家推荐的都是自己的ip来做负载,但是同样有说DNS负载均衡,刚开始我也是一头雾水,慢慢的分析才知道真正意义上的Nginx+DNS负载均衡。1.nginx负载均衡的5种策略(先了解这个后面的才好懂)轮询策略(默认)这种策略下每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。upstreambackserver{server192.168.0.14;server192.168.0.15;}指定

    2022年7月14日
  • 电信光纤友华PT921G,烽火HG220光猫激活成功教程关闭自带路由改桥接拨号教程[通俗易懂]

    电信光纤友华PT921G,烽火HG220光猫激活成功教程关闭自带路由改桥接拨号教程[通俗易懂]电信光纤友华PT921G光猫激活成功教程关闭自带路由改桥接拨号教程电信光猫质量烂就算了,最受不了它自带的路由还做了手脚,导致VPN用不了。不让看AV就算了,打个外服游戏总可以吧?不知道为啥,网上关于光猫改桥接的教程基本没有,搜出来的也说得很不清楚,是和谐了还是什么原因不得而知。本人也是自己自己试出来的,其实修改难度并不大,只不过那个界面搞的特奇葩特不友好罢了。废话不多说,步骤如下:

    2022年6月24日
  • 百度分享js代码_javascript基础代码

    百度分享js代码_javascript基础代码转自:http://www.internetke.com/effects/run/2013/1108/117.html更多document.getElementById(“bdshell_js”).src=”http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=”+Math.ceil(new

    2022年10月8日
  • 有关微信登录小程序接口40029报错

    有关微信登录小程序接口40029报错有关微信登录小程序接口40029报错微信的报错信息errcode:40029,errmsg:"invalidcode,hints:[req_id:HQd79a0747th31]我的可能是例外,但是应该不是个例!微信验签等代码是copy上一个项目的!而且我的项目用上一个的小程序/公众号写过测试,小程序/公众号中做过相应配置!所以以上错误很可能是你的APPID和app_…

    2022年5月5日
  • matlab中imfilter函数是什么意思_matlab中bwlabel函数

    matlab中imfilter函数是什么意思_matlab中bwlabel函数Matlab函数imfill简介函数功能:该函数用于填充图像区域和“空洞”。语法格式:BW2=imfill(BW)这种格式将一张二值图像显示在屏幕上,允许用户使用鼠标在图像上点几个点,这几个点围成的区域即要填充的区域。要以这种交互方式操作,BW必须是一个二维的图像。用户可以通过按Backspace键或者Delete键来取消之前选择的区域;通过shift+鼠标左键单击或者鼠…

    2022年9月13日
  • navicate15 激活码_在线激活

    (navicate15 激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html0VOERWDQ5R-eyJsaWN…

    2022年3月31日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号