全世界人民都知道单例设计模式中类的定义分为懒汉式和饿汉式两种,然而今天并不是要把它们做横向比较。实际上,不论饿汉式类的代码看起来有多么美轮美奂,在实际开发中它的效率总是不如懒汉式的。然而在笔试和面试中懒汉式的出镜率可以说是比饿汉式不知道高到哪里去了,因此把它完全弄懂应该是十分有必要的。

饿汉式:

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单例设计模式中懒汉式类定义的讨论的更多相关文章

  1. java设计模式--解决单例设计模式中懒汉式线程安全问题

    首先写个单例,懒汉模式: public class SingleDemo { private static SingleDemo s = null; private SingleDemo(){} pu ...

  2. java软件设计模式——单例设计模式中的【饿汉式】与 【懒汉式】示例

    以下为单例设计模式中的两种经典模式的代码示意: 单例设计模式(spring框架IOC,默认创建的对象都是单例的): 饿汉式: public class SingleClass { private Si ...

  3. Java单例设计模式的实现

    1. 单例设计模式的定义 单例设计模式确保类只有一个实例对象,类本身负责创建自己的对象并向整个系统提供这个实例.在访问这个对象的时候,访问者可以直接获取到这个唯一对象而不必由访问者进行实例化. 单例设 ...

  4. 转:java单例设计模式

    本文转自:http://www.cnblogs.com/yinxiaoqiexuxing/p/5605338.html 单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton ...

  5. 菜鸡的Java笔记 第二十九 - java 单例设计模式

    SingleCase 单例设计模式        1.单例设计模式的特点        2.多例设计模式的特点    内容    单例设计模式        现在如果说有这么一个程序类 class S ...

  6. Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式

    (一)java.util.Date类 1.该类有一个long类型的属性:用来存放时间,是用毫秒数的形式表示,开始的日期是从1970年1月1号 00:00:00.    2.该类的很多方法都已经过时,不 ...

  7. Java 单例设计模式之 饿汉式和懒汉式

    public class InstanceSampleTest { public static void main(String[] args) { /** 单例设计模式的 饿汉式和懒汉式 * 单例模 ...

  8. Java单例设计模式(实现Java的一个类只有一个对象)

    单例设计模式的定义:单例设计模式是一种软件设计模式,在它的核心包含一个称为单例类的核心类. 核心便是希望一个类只有一个对象.  如何实现类在内存中只有一个对象呢? 第一步:构造私有:第二步:本身提供一 ...

  9. Java——单例设计模式

    设计模式:解决某一类问题最行之有效的方法.Java中23种设计模式:单例设计模式:解决一个类在内存中只存在一个对象. 想要保证对象唯一.1,为了避免其他程序过多建立该类对象.先禁止其他程序建立该类对象 ...

随机推荐

  1. springmvc 学习

    第一章回顾JavaWeb中的MVC设计模式 1)MVC这种设计模式,不光运用于Web领域,而且也能用于非Web领域 2)今天说的MVC特指一种表现层设计模式,不限于Java语言 第二章回顾struts ...

  2. Java学习之代码块(静态,构造代码块,构造方法)执行顺序

    静态代码块   static{ 代码 } 随着类的加载而加载,随类的消失而消失,存在于类中,方法外,最先执行,且只加载1次,可用来加载驱动及初始化对象属性. 构造代码块   {   } 也存在于类中, ...

  3. Java开发体系

    蓦然回首自己做开发已经十年了,这十年中我获得了很多,技术能力.培训.出国.大公司的经历,还有很多很好的朋友.但再仔细一想,这十年中我至少浪费了五年时间,这五年可以足够让自己成长为一个优秀的程序员,可惜 ...

  4. Spring Security 理解小记

    JWT 框架图如下, 来自博客https://blog.csdn.net/shehun1/article/details/45394405 个人觉得还不错.. 在开发中Spring boot 启用 加 ...

  5. jakarta-taglibs-standard-1.1.0查找下载

  6. 解析如何实现微信唤醒默认浏览器下载app教程!

    前言 现如今微信对第三方app下载链接的拦截是越来越严格了,下载链接在微信中分享转发经常会被拦截,一旦被拦截用户就只能复制链接手动打开浏览器粘贴才能访问,如此给用户带来的体验台差,用户量无法有效地累积 ...

  7. Java学习--变量

    参考  http://www.runoob.com/java/java-variable-types.html java变量使用前 java中的所有变量在使用前必须声明并且初始化 类变量和实例变量会默 ...

  8. 什么是jquery

    框架就是一个半成品,不能直接使用,需要加工处理后才可使用

  9. unfortunately,*********** has stopped及卸载模拟器上的多余不用apk

    虽然不知道是怎么了,但是项目进不去了,害的我一脸雾水,百度了下好像没什么人遇到过这问题,都没找到解决办法,那只好来个简单粗暴的,卸载重新安装apk ,希望有大神知道原因和其他方法的欢迎留言或者评价给出 ...

  10. Java框架spring 学习笔记(九):Spring的bean管理(@Required、@Component、@Autowired、@Resource注解)

    注解:代码里面特殊的标记,使用注解可以完成相关功能 注解写法:@注解名称(属性名.属性值) @Required 用在set方法上,一旦用了这个注解,那么容器在初始化bean的时候必须要进行set,也就 ...