对Java单例设计模式中懒汉式类定义的讨论
全世界人民都知道单例设计模式中类的定义分为懒汉式和饿汉式两种,然而今天并不是要把它们做横向比较。实际上,不论饿汉式类的代码看起来有多么美轮美奂,在实际开发中它的效率总是不如懒汉式的。然而在笔试和面试中懒汉式的出镜率可以说是比饿汉式不知道高到哪里去了,因此把它完全弄懂应该是十分有必要的。
饿汉式:
class Single1
{
int num = 1;
private static Single1 single1 = new Single1();
private Single1(){}
static Single1 getInstance1()
{
return single1;
}
}
最简单的懒汉式:
class Single2
{
int num = 2;
private static Single2 single2 = null;
private Single2(){}
static Single2 getInstance2()
{
//如果两个线程同时访问,有可能会生成两个实例,不符合单例模式的要求
if(single2 == null)
single2 = new Single2();
return single2;
}
}
然而这样的类定义实际上是线程不安全的。正如注释上说的,因为线程的不确定性无法确认它们在访问Single2 = new Single2();时是否已经有一个Single2的实例生成。在面试中如果写出这样一个代码,往往会被追问如果改进能让它线程安全。根据一般思路,我们对代码做出如下改进:
class Single2
{
int num = 2;
private static Single2 single2 = null;
private Single2(){}
static Object obj = new Object(); //创建同步锁对象
static Single2 getInstance2()
{ synchronized(obj) //同步锁,确保某一时刻只有一个线程能够访问内部模块
{
if(single2 == null)
single2 = new Single2();
return single2;
}
}
}
代码经过以上的改进可以解决线程不安全问题,然而此时可能又会被问到:这样虽然能解决线程不安全问题,但是同时却降低了程序的效率,如何改进代码?其实在外层再添加一个条件判断语句就可以了。
class Single2
{
int num = 2;
private static Single2 single2 = null;
private Single2(){}
static Object obj = new Object();
static Single2 getInstance2()
{
if(single2 == null)
{
synchronized(obj)
{
if(single2 == null)
single2 = new Single2();
}
}
return single2;
}
}
完美了,估计没有什么好问的了,测试一下。
public class Single
{
public static void main(String[] args)
{
Single1 s1 = Single1.getInstance1();
Single2 s2 = Single2.getInstance2();
System.out.println(s1.num+".."+s2.num);
}
}
输出结果:
1..2
没毛病!
对Java单例设计模式中懒汉式类定义的讨论的更多相关文章
- java设计模式--解决单例设计模式中懒汉式线程安全问题
首先写个单例,懒汉模式: public class SingleDemo { private static SingleDemo s = null; private SingleDemo(){} pu ...
- java软件设计模式——单例设计模式中的【饿汉式】与 【懒汉式】示例
以下为单例设计模式中的两种经典模式的代码示意: 单例设计模式(spring框架IOC,默认创建的对象都是单例的): 饿汉式: public class SingleClass { private Si ...
- Java单例设计模式的实现
1. 单例设计模式的定义 单例设计模式确保类只有一个实例对象,类本身负责创建自己的对象并向整个系统提供这个实例.在访问这个对象的时候,访问者可以直接获取到这个唯一对象而不必由访问者进行实例化. 单例设 ...
- 转:java单例设计模式
本文转自:http://www.cnblogs.com/yinxiaoqiexuxing/p/5605338.html 单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton ...
- 菜鸡的Java笔记 第二十九 - java 单例设计模式
SingleCase 单例设计模式 1.单例设计模式的特点 2.多例设计模式的特点 内容 单例设计模式 现在如果说有这么一个程序类 class S ...
- Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式
(一)java.util.Date类 1.该类有一个long类型的属性:用来存放时间,是用毫秒数的形式表示,开始的日期是从1970年1月1号 00:00:00. 2.该类的很多方法都已经过时,不 ...
- Java 单例设计模式之 饿汉式和懒汉式
public class InstanceSampleTest { public static void main(String[] args) { /** 单例设计模式的 饿汉式和懒汉式 * 单例模 ...
- Java单例设计模式(实现Java的一个类只有一个对象)
单例设计模式的定义:单例设计模式是一种软件设计模式,在它的核心包含一个称为单例类的核心类. 核心便是希望一个类只有一个对象. 如何实现类在内存中只有一个对象呢? 第一步:构造私有:第二步:本身提供一 ...
- Java——单例设计模式
设计模式:解决某一类问题最行之有效的方法.Java中23种设计模式:单例设计模式:解决一个类在内存中只存在一个对象. 想要保证对象唯一.1,为了避免其他程序过多建立该类对象.先禁止其他程序建立该类对象 ...
随机推荐
- DAO(Repository),Service,Controller层之间的相互关系
DAO层:DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口 ...
- 基于HALCON的模板匹配方法总结
注:很抱歉,忘记从转载链接了,作者莫怪.... 基于HALCON的模板匹配方法总结 很早就想总结一下前段时间学习HALCON的心得,但由于其他的事情总是抽不出时间.去年有过一段时间的集中学习,做了许多 ...
- 6Linux用户身份与文件权限
3类用户身份: (1)管理员UID为0,root (2)系统用户UID为1-999:nologin不能登录系统,老版本5.6中是1-499 (3)普通用户UID为1000开始,老版本5.6中是1000 ...
- win10以管理员身份运行cmd方法
win10以管理员身份运行cmd方法 win8win10以管理员身份运行cmd方法1.直接到 C:\Windows\System32 下面找cmd.exe 右键以管理员方式打开就可以了 2.按WIN+ ...
- 关于background-size 的一点小坑
目前在做一个网页,要求使用一个图片作为背景,必须要全屏目填充,于是我想,这不是很简单的事情么: 有两种实现方法:首先设置添加一个div(或者body),把div(或者body)元素的宽和高都设置成10 ...
- 为什么打开fiddler电脑就不能上网,关了就能正常打开了呢?
因为打开fiddler是它修改浏览器走代理服务器,关掉fiddler之后,代理服务器已经关闭了.但是,但是浏览器的代理模式还没改回来,就是说浏览器还要通过代理访问站点,然而代理服务器已经没有了.打开浏 ...
- anujs1.4.0发布
经过三个月的埋头苦干,终于完成Fiber版的anujs. 主要特性有: 测试全部改成jest, 迁移官方测试用例.有许多迷你React吹得怎么天花乱坠,但是生命周期钩子的执行顺序无法与官方保持一致,那 ...
- springboot使用内部tomcat启动和外部tomcat启动的区别
springboot本身提供了内部tomcat,可以使用main方法直接启动即可,此时在访问项目请求时,不需要加上项目名称.例如:http://localhost:8088/user/ 如果使用外部t ...
- KeyValuePair 和 Dictionary 的关系和区别
KeyValuePair 和 Dictionary 的关系 1.KeyValuePair a.KeyValuePair 是一个结构体(struct): b.KeyValuePair ...
- C# 小算法1
//判断 第一条的 ‘叶子2’ 在 第二条 数据中的 索引 //任河特大桥,右幅,叶子2,桩基混凝土, //任河特大桥,,,,,右幅,,,叶子2,桥墩, string str1 = "任河特 ...