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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • c++ 11 bind_箭头函数可以用bind吗

    c++ 11 bind_箭头函数可以用bind吗bind函数的使用详解可以将bind函数看作是一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。调用bind的一般形式:autonewCallable=bind(callable,arg_list);`其中,newCallable本身是一个可调用对象,arg_list是一个逗号分隔的参数列表,对应给定的callable的参数。即,当我们调用n……

    2025年7月8日
    0
  • Kettle实战视频教程

    Kettle实战视频教程呕心沥血制作的kettle视频教程,免费提供给大家,只要学不死,就往死里学,加油吧少年学完本课程,您将掌握:掌握kettle的基础知识,进阶知识和实际工作中的各种情况适合人群:1、熟悉数据库,想学习ETL的同学,想快速提升竞争力的ETL工程师2、运维相关工作人员课程目标:能够掌握实际工作中遇到的迁移和业务各种实际工作内容课程简介:1、本教程不是单纯的各种控件进行逐个讲解2、所有知识点均全部为项目实战的介绍和总结3、单表和全表所有的同步4、本视频由浅入深,再由深入浅,循序渐进逐步

    2022年5月23日
    32
  • mybatiscodehelperpro激活成功教程2.8.4_Mybatis框架

    mybatiscodehelperpro激活成功教程2.8.4_Mybatis框架#MyBatisCodeHelperPro2.9插件[2022最新有效]一、下载二、使用步骤1.引入库代码如下(示例):importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltimportseabornassnsimportwarningswarnings.filterwarnings(‘ignore’)importsslssl._create_default_https_contex

    2022年9月16日
    0
  • ClientScript.RegisterStartupScript

    ClientScript.RegisterStartupScriptClientScript.RegisterStartupScript用来向前台页面注册script脚本。//此处是从页面接受变量,然后弹出  stringmm=Request[“name”];  stringyhm=Request[“pswd”];   ClientScript.RegisterStartupScript(this.GetType(),”message”,”cri

    2022年7月20日
    18
  • pip怎么卸载安装包_pip删除安装包

    pip怎么卸载安装包_pip删除安装包1、pip下载安装1.1pip下载进入https://pypi.python.org/pypi/pip,下载.tar.gz压缩包1.2Linux安装pip#tar-xzvfpip-1.5.4.tar.gz解压#cdpip-1.5.4进入解压文件#pythonsetup.pyinstall安装1.3升级pippython-mpipinstall–upgradepip2.pi…

    2022年10月9日
    0
  • 词袋模型和词向量模型

    词袋模型和词向量模型本文简要介绍了词袋模型、词向量模型的原理和应用。

    2022年6月13日
    40

发表回复

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

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