一、单例模式(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. 今天遇到的面试题for(j=0,i=0;j<6,i<10;j++,i++) { k=i+j; } k 值最后是多少?

    for(j=0,i=0;j<6,i<10;j++,i++) { k=i+j; } k 值最后是多少? <script type="text/javascript" ...

  2. Matlab中plot函数全功能解析

    Matlab中plot函数全功能解析 功能 二维曲线绘图 语法 plot(Y)plot(X1,Y1,...)plot(X1,Y1,LineSpec,...)plot(...,'PropertyName ...

  3. 创建Win32图形界面应用程序

    没有什么比创建一个Win32图形界面应用程序能让Win32汇编初学者更兴奋的了! 然而,对于像我这样没有代码便会陷入困境的人来说,看到下面的代码总能让人为之一振,百余行的代码使得Win32GUI编程并 ...

  4. android学习7——canvas.concat(Matrix matrix)作用

    canvas.concat的作用可以理解成对matrix的变换应用到canvas上的所有对象. 看下面的代码. public class ConcatMatrixActivity extends Ac ...

  5. Web Service ,WCF以及Web API的对比

    Web Service 1.基于SOAP和XML形式的返回数据. 2.只支出HTTP协议. 3.只能运行在IIS环境下. 4.不是开源的,但可以由任何支持xml的客户端下使用. WCF 1.基于SOA ...

  6. [Hadoop] - Cannot run program "cmake"

    在编译hadoop的过程中,遇到缺少cmake命令的异常,异常信息为:Cannot run program "cmake" (in directory "/opt/wor ...

  7. ERP管理员培训报道

    金秋十月,丹桂飘香,为期三天的“201610管理员培训”活动于2016年10月19日在苏州总部成功举行.参与本次培训活动的有浙江卡迪夫电缆有限公司.上海华源瓷业股份有限公司.江苏牛牌纺织机械有限公司. ...

  8. table标签中thead、tbody、tfoot的作用

    为了让大表格(table)在下载的时候可以分段的显示,就是说在浏览器解析HTML时,table是作为一个整体解释的,使用tbody可以优化显示.如果表格很长,用tbody分段,可以一部分一部分地显示, ...

  9. java装箱跟拆箱解析

    /** * 在jdk1.5之后,java为基本数据类型到对应的应用数据类型提供了自动拆箱装箱操作 * 不管是自动拆箱还是自动装箱都是应用数据类型有的方法,基本数据类型是没有任何方法可调用的 *从概念上 ...

  10. 3402: [Usaco2009 Open]Hide and Seek 捉迷藏

    3402: [Usaco2009 Open]Hide and Seek 捉迷藏 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 78  Solved: 6 ...