一、单例模式(Singleton)

1、单例模式应用场景:

  ①Servlet
  ②任务管理器
  ③链接池
  ④Spring中每个 bean 默认是单例
  ⑤网站计数器

2、单例要求

  ①构造器私有
  ②私有的静态变量
  ③公共的静态的可以访问私有的静态变量的方法

结论:由结果可以得知单例模式为一个面向对象的应用程序提供了对象惟一的访问点,不管它实现何种功能,整个应用程序都会同享一个实例对象。
二、单例模式的实现方式

1、饿汉式
  线程安全、立即加载、资源利用率低、调用效率高

package cn.com.zfc.gof01.singleton;

/**
*
* @title Singleton01
* @describe 饿汉式实现单例模式
* @author 张富昌
* @date 2017年3月27日上午8:40:02
*/
public class Singleton01 {

  // 天然的线程安全的,类加载是立即加载这个实例
  private static Singleton01 instance = new Singleton01();

  / 构造器私有化
  private Singleton01() {

  }

  // 方法没有同步,效率比较高
  public static Singleton01 getInstance() {
    return instance;
  }
}

2、懒汉式
  线程安全、延迟加载、资源利用率高、调用效率低

package cn.com.zfc.gof01.singleton;

/**
*
* @title Singleton02
* @describe 懒汉式实现单例模式
* @author 张富昌
* @date 2017年3月27日上午8:45:42
*/
public class Singleton02 {

  private static Singleton02 instance = null;

  //构造其私有化
  private Singleton02() {
  }

  //公共,同步,静态
  public static synchronized Singleton02 getInstance() {
    if (instance == null) {
      instance = new Singleton02();
    }
    return instance;
  }
}

3、双重检索式
  线程安全、延迟加载、资源利用率高、调用效率高、但不稳定

package cn.com.zfc.gof01.singleton;

/**
*
* @title Singleton03
* @describe 双重检测锁式实现单例模式(不建议使用)
* @author 张富昌
* @date 2017年3月27日上午8:52:59
*/
public class Singleton03 {

  private static Singleton03 instance = null;

  private Singleton03() {

  }

  public static Singleton03 getInstance() {
    if (instance == null) {
      Singleton03 sc;
      synchronized (Singleton03.class) {
        sc = instance;
        if (sc == null) {
          synchronized (Singleton03.class) {
            if (sc == null) {
              sc = new Singleton03();
            }
          }
          instance = sc;
        }
      }
    }
    return instance;
  }

}

4、静态内部类式(相比于懒汉式更好)
  线程安全、延迟加载、资源利用率高、调用效率高

package cn.com.zfc.gof01.singleton;

/**
*
* @title Singleton04
* @describe 静态内部类式实现单例模式
* @author 张富昌
* @date 2017年3月27日上午8:54:40
*/
public class Singleton04 {

  // 构造器私有化
  private Singleton04() {

  }

  // 静态内部类
  private static class StaticInnerClass {
    private static final Singleton04 INSTANCE = new Singleton04();
  }

  public static Singleton04 getInstance() {
    return StaticInnerClass.INSTANCE;
  }

}

5、枚举单例式(相比于饿汉式更好)
  线程安全、立即加载、可以天然的防止反射和反序列化

package cn.com.zfc.gof01.singleton;

/**
*
* @title Singleton05
* @describe 枚举式实现单例模式
* @author 张富昌
* @date 2017年3月27日上午9:01:59
*/
public enum Singleton05 {
  // 单例对象
  INSTANCE;

  // 如果要对该单例对象进行额外的操作,则加入方法
  public void singlrtonOperation() {

  }

}

三、测试多线程环境下五种创建单例模式的效率

package cn.com.zfc.gof01.singleton.test;

import java.util.concurrent.CountDownLatch;

import cn.com.zfc.gof01.singleton.Singleton05;

/**
*
* @title SingletonTest
* @describe 测试多线程环境下五种创建单例模式的效率
* @author 张富昌
* @date 2017年3月27日上午9:24:58
*/
public class SingletonTest {
  public static void main(String[] args) throws Exception {

    long start = System.currentTimeMillis();
    int threadNum = 10;
    // A synchronization aid that allows one or more threads to wait until a
    // set of operations being performed in other threads completes.
    // 计数器(一个线程执行完成就减1)
    final CountDownLatch countDownLatch = new CountDownLatch(threadNum);

    for (int i = 0; i < threadNum; i++) {
      // 多线程测试
      new Thread(new Runnable() {
        @Override
        public void run() {

          for (int i = 0; i < 1000000; i++) {
            // 饿汉式,
            // Object o = Singleton01.getInstance();
            // 懒汉式,最慢
            // Object o = Singleton02.getInstance();
            // 双重检测锁式,不稳定,不建议使用
            // Object o = Singleton03.getInstance();
            // 静态内部类
            // Object o = Singleton04.getInstance();
            // 枚举式
            Object o = Singleton05.INSTANCE;
          }

          // 一个线程执行完成就减1
          countDownLatch.countDown();
        }
      }).start();
    }

    // 阻塞
    countDownLatch.await(); // main线程阻塞,直到计数器变为0,才会继续往下执行!

    long end = System.currentTimeMillis();
    System.out.println("总耗时:" + (end - start));
  }
}

四、什么是线程安全?

  如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

  或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题,那就是线程安全的。

Java设计模式GOF之单例模式的更多相关文章

  1. Java设计模式之《单例模式》及应用场景

    摘要: 原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6510196.html 所谓单例,指的就是单实例,有且仅有一个类实例,这个单例不应该 ...

  2. Java设计模式之【单例模式】

    Java设计模式之[单例模式] 何为单例 在应用的生存周期中,一个类的实例有且仅有一个 当在一些业务中需要规定某个类的实例有且仅有一个时,就可以用单例模式 比如spring容器默认初始化的实例就是单例 ...

  3. Java设计模式GOF之6大设计原则

    Java设计模式GOF之6大设计原则原则 1.开闭原则(Open Close Principle) 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 开闭原则是面向对象的可复用设计的第一块基石 ...

  4. Java设计模式中的单例模式

    有时候在实际项目的开发中,我们会碰到这样一种情况,该类只允许存在一个实例化的对象,不允许存在一个以上的实例化对象,我们将这种情况称为Java设计模式中的单例模式.设计单例模式主要采用了Java的pri ...

  5. 重学 Java 设计模式:实战单例模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 5个创建型模式的最后一个 在设计模式中按照不同的处理方式共包含三大类:创建型模式.结 ...

  6. java设计模式-----4、单例模式

    单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的一个实例对象.也就是说,在整个程序空间中,该类只存在一个实例对象. 其实,GoF对单例模式的定义是:保证一个类,只有一个实例存在 ...

  7. Java设计模式4:单例模式

    前言 非常重要,单例模式是各个Java项目中必不可少的一种设计模式.本文的关注点将重点放在单例模式的写法以及每种写法的线程安全性上.所谓"线程安全性"的意思就是保证在创建单例对象的 ...

  8. 10.Java设计模式 工厂模式,单例模式

    Java 之工厂方法和抽象工厂模式 1. 概念 工厂方法:一抽象产品类派生出多个具体产品类:一抽象工厂类派生出多个具体工厂类:每个具体工厂类只能创建一个具体产品类的实例. 即定义一个创建对象的接口(即 ...

  9. Java设计模式探讨之单例模式

    单例模式是在平时的项目开发中比较常见的一种设计模式,使用比较普遍,网上的资料也是一抓一大把,小Alan也来凑凑热闹,为以后充实点设计模式相关的内容做个简单的开篇. 单例模式是一种创建对象的模式,用于产 ...

随机推荐

  1. 读书笔记 effective c++ Item 13 用对象来管理资源

    1.不要手动释放从函数返回的堆资源 假设你正在处理一个模拟Investment的程序库,不同的Investmetn类型从Investment基类继承而来, class Investment { ... ...

  2. 前端开发面试题总结之——JAVASCRIPT(一)

    ___________________________________________________________________________________ 相关知识点 数据类型.运算.对象 ...

  3. Flash、Ajax各自的优缺点,在使用中如何取舍?

    1.Flash ajax对比 Flash适合处理多媒体.矢量图形.访问机器:对CSS.处理文本上不足,不容易被搜索. Ajax对CSS.文本支持很好,支持搜索:多媒体.矢量图形.机器访问不足. 共同点 ...

  4. 配置opencv环境

    包含目录:解决代码报错问题 F:\ndk\opencv-windows\opencv\build\include;F:\ndk\opencv-windows\opencv\sources\includ ...

  5. 8086cpu

    1.  8086CPU和8088CPU内部结构基本相同,不同之处在于8088有8条外部数据总线,因此为准16位.8086有16条外部数据总线.两个CPU的软件完全兼容,程序的编制也完全相同. 2.   ...

  6. 自定义checkbox/radio

    一. label标签 1. 概念: HTML <label>元素表示用户界面中项目的标题.它通常关联一个控件,或者是将控件放置在label元素内,或者是用作其属性.这样的控制称作label ...

  7. TempDB问题定位与解决

    步骤1.TempDB压力诊断 等待类型诊断 TempDB的争用压力在等待篇中已经简单介绍,等待的表现为 pagelatch_类等待,等待的资源是 “2: X :X ” tempDB所在磁盘的响应时间 ...

  8. webservice基本功能介绍

    WebService, 能使得运行在不同机器上的不同应用无须借助附加的.专门的第三方软件或硬件, 就可相互交换数据或集成.依据WebService规范实施的应用之间, 无论它们所使用的语言. 平台或内 ...

  9. 前端学PHP之日期与时间

    前面的话 在Web程序开发时,时间发挥着重要的作用,不仅在数据存储和显示时需要日期和时间的参与,好多功能模块的开发,时间通常都是至关重要的.网页静态化需要判断缓存时间.页面访问消耗的时间需要计算.根据 ...

  10. python之SQLAlchemy ORM 上

    前言: SQLAlchmey是暑假学的,当时学完后也没及时写博客整理下.这篇博客主要介绍下SQLAlchemy及基本操作,写完后有空做个堡垒机小项目.下篇博客整理写篇关于Web框架和django基础~ ...