一、单例模式(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. enote笔记语言(3)(ver0.2)

    what&why(why not)&how&when&where&which:紫色,象征着神秘而又潜蕴着强大的力量,故取紫色. key&keyword: ...

  2. BZOJ 1834: [ZJOI2010]network 网络扩容(网络流+费用流)

    一看就知道是模板题= = ,不说什么了= = PS:回去搞期末了,暑假再来刷题了 CODE: #include<cstdio> #include<iostream> #incl ...

  3. linux下载时提示请尝试移除磁盘中不需要的文件并重试,或者保存到其他位置

    因为我是用虚拟机装的linux,所以当时就分配了20G硬盘,下载了几个应用后再下载就提示我这个了.一开始我还以为是因为下载链接的问题,后来才知道原来是因为/tmp的满了. 然后我输入以下连个命令就能正 ...

  4. 读书笔记 effective c++ Item 22 将数据成员声明成private

    我们首先看一下为什么数据成员不应该是public的,然后我们将会看到应用在public数据成员上的论证同样适用于protected成员.最后够得出结论:数据成员应该是private的. 1. 为什么数 ...

  5. 【转】对于HttpClient和HtmlUnit的理解

    原文地址:http://www.haohaoblog.com/?p=1327&utm_source=tuicool 做Java编程的人其实,很多不懂SEO,也不知道如何让百度收录等等,当然,对 ...

  6. 【前端】:jQuery实例

    前言: 今天2月最后一天,写一篇jQuery的几个实例,算是之前前端知识的应用.写完这篇博客会做一个登陆界面+后台管理(i try...) 一.菜单实例 最开始的界面: 点击菜单三后的界面: < ...

  7. LAMP部署

    各组件版本:Linux:CentOS 7 1511 64位 (提前下载)Apache:Apache 2Mysql:MariaDB 5.5.52Php 5.4.16 VMware Workstation ...

  8. Redis Cluster部署、管理和测试

    背景: Redis 3.0之后支持了Cluster,大大增强了Redis水平扩展的能力.Redis Cluster是Redis官方的集群实现方案,在此之前已经有第三方Redis集群解决方案,如Twen ...

  9. 禁止linux被ping

    cho "net.ipv4.icmp_echo_ignore_all=1" >> /etc/sysctl.conf sysctl -p 生效 开启ping功能: 删除/ ...

  10. Java设计模式之《观察者模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6513651.html 观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监 ...