单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

单例模式的创建方式,主要有四种:

  • 饿汉模式
  • 懒汉模式
    • 普通模式
    • 懒汉模式
    • 双重校验锁

饿汉模式

顾名思义,就是非常的饥饿,立即的创建单例模式。

public class HungrySingleton {

  //饿汉模式,立即创建对象
private static HungrySingleton hungrySingleton = new HungrySingleton(); /** 私有化构造方法 */
private HungrySingleton() {} /**
* 获取单例实例
*
* @return
*/
public static HungrySingleton getInstance() {
rturn hungrySingleton;
}
}

这种模式具有以下特点:

  • 线程安全,避免了多线程同步问题
  • 没有达到懒加载的效果

懒汉模式

懒汉模式,就在在创建实例的时候不初始化,待到需要获取实例对象的时候在判断,是不是尚未实例化,是的话进行实例化对象,然后返回,否则直接返回简单的懒汉模式如下:

public class LazySingleton {

  private static LazySingleton lazySingleton = null;

  /** 私有化构造方法 */
private LazySingleton() {} /**
* 获取单例实例
*
* @return
*/
public static LazySingleton getInstance() {
//检查判断,没有初始化的时候尝试初始化
if (lazySingleton == null) {
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}

虽然这种模式能够达到懒加载的目的,提高了性能,但是线程不安全,无法避免多线程的问题,在多线程的操作下,可能会出现实例化多个对象的情况,违反了单例的约束条件。

所以我们可以为初始化添加校验锁,如下:

public class LazySyncSingleton {

  private static LazySyncSingleton lazySyncSingleton = null;

  /** 私有化构造方法 */
private LazySyncSingleton() {} /**
* 获取单例实例
*
* <p>添加了 synchronized 锁机制
*
* @return
*/
public static synchronized LazySyncSingleton getInstance() {
if (lazySyncSingleton == null) {
lazySyncSingleton = new LazySyncSingleton();
}
return lazySyncSingleton;
}
}

但是需要注意的是,我们初始化只在第一次调用hetInstance的时候,尝试初始化,后期我们都是直接返回对象,假设我们创建好了对象,存在多个线程获取对象,那么每个线程都要等待其他线程执行完成之后在执行获取实例,这种设计模式,性能非常低,因此我们利用DCL(Double Check Lock,双重校验锁)来实现

public class DoubleCheckLockSingleton {

  private static volatile DoubleCheckLockSingleton doubleCheckLockSingleton;

  private DoubleCheckLockSingleton() {}

  private static DoubleCheckLockSingleton getInstance() {
if (doubleCheckLockSingleton == null) {
synchronized (DoubleCheckLockSingleton.class) {
if (doubleCheckLockSingleton == null) {
doubleCheckLockSingleton = new DoubleCheckLockSingleton();
}
}
}
return doubleCheckLockSingleton;
}
}

DCL机制是一个非常好的设计理念,不仅仅只用在Sign'leton Pattern中,其他的地方均可以合理利用。

设计模式系列之单例模式(Singleton Pattern)的更多相关文章

  1. 设计模式系列之单例模式(Singleton Pattern)——确保对象的唯一性

    模式概述 模式定义 模式结构图 饿汉式单例与懒汉式单例 饿汉式单例 懒汉式单例 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 主要优点 适用场景 说明:设计模式系列文章是读刘伟所著 ...

  2. Net设计模式实例之单例模式( Singleton Pattern)

    一.单例模式简介(Brief Introduction) 单例模式(Singleton Pattern),保证一个类只有一个实例,并提供一个访问它的全局访问点.单例模式因为Singleton封装它的唯 ...

  3. 浅谈设计模式--单例模式(Singleton Pattern)

    题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...

  4. 设计模式之单例模式(Singleton Pattern)

    单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ...

  5. 乐在其中设计模式(C#) - 单例模式(Singleton Pattern)

    原文:乐在其中设计模式(C#) - 单例模式(Singleton Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 单例模式(Singleton Pattern) 作者:weba ...

  6. 【设计模式】单例模式 Singleton Pattern

    通常我们在写程序的时候会碰到一个类只允许在整个系统中只存在一个实例(Instance)  的情况, 比如说我们想做一计数器,统计某些接口调用的次数,通常我们的数据库连接也是只期望有一个实例.Windo ...

  7. 二十四种设计模式:单例模式(Singleton Pattern)

    单例模式(Singleton Pattern) 介绍保证一个类仅有一个实例,并提供一个访问它的全局访问点. 示例保证一个类仅有一个实例. Singleton using System; using S ...

  8. 【白话设计模式四】单例模式(Singleton)

    转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...

  9. 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)

    在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...

随机推荐

  1. [Swift]LeetCode513. 找树左下角的值 | Find Bottom Left Tree Value

    Given a binary tree, find the leftmost value in the last row of the tree. Example 1: Input: 2 / \ 1 ...

  2. [Swift]LeetCode516. 最长回文子序列 | Longest Palindromic Subsequence

    Given a string s, find the longest palindromic subsequence's length in s. You may assume that the ma ...

  3. [Swift]LeetCode929. 独特的电子邮件地址 | Unique Email Addresses

    Every email consists of a local name and a domain name, separated by the @ sign. For example, in ali ...

  4. springboot 实战之一站式开发体验

    都说springboot是新形势的主流框架工具,然而我的工作中并没有真正用到springboot: 都说springboot里面并没有什么新技术,不过是组合了现有的组件而已,但是自己却说不出来: 都说 ...

  5. Python面试真题答案或案例

    Python面试真题答案或案例如下: 请等待. #coding=utf-8 #1.一行代码实现1--100之和 print(sum(range(1,101))) #2.如何在一个函数内部修改全局变量 ...

  6. 6种字符串数组的java排序 (String array sort)

    注意,本文不是字符串排序,是字符串数组的排序. 方法分别是: 1.低位优先键索引排序 2.高位优先建索引排序 3.Java自带排序(经过调优的归并排序) 4.冒泡排序 5.快速排序 6.三向快速排序 ...

  7. How does the vuejs add the query and walk the object?

    让这个老实返回的页面添加特殊路由,这个页面常常都是登录注册.这次我们根据登录举例. 省略 { path:'/login?url=:url', name:'loginfirst', component: ...

  8. Unity资源打包学习笔记(一)、详解AssetBundle的流程

    转载请标明出处:http://www.cnblogs.com/zblade/ 本文参照unity官网上对于assetBundle的一系列讲解,主要针对assetbundle的知识点做一个梳理笔记,也为 ...

  9. nodejs操作session和cookie

    session: 安装模块 cnpm install express-session 引入session注册到路由 var express = require('express'); var sess ...

  10. java web 项目打包(war 包)并部署

    1.在eclipse中右键单击项目,然后Export选择WAR file,生成项目的WAR文件.具体步骤请看图片详细操作步骤: 2.把生成的WAR文件放到tomcat解压之后的webapps文件夹下. ...