概念:在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。

单例模式从实现上可以分为饿汉式单例懒汉式单例两种,前者天生就是线程安全的,后者则需要考虑线程安全性,常见的线程安全的懒汉式单例的实现有内部类式双重检查式两种。下面给出单例模式几种常见的形式:

(1)饿汉式单例

单例模式的核心有两点:

  • 私有化的构造方法
  • 公有化的静态的getInstance方法
/**
* 恶汉式单例模式
* @author Xia
*/
public class Singleton {
//指向自己实例的私有静态引用,主动创建
private static Singleton instance = new Singleton();
//私有的构造方法
private Singleton(){} //以自己实例为返回值的静态的公有方法,静态工厂方法
public static Singleton getInstance(){
return instance;
}
}

(2)懒汉式单例

懒汉式单例的核心点:

  • 私有化的构造方法
  • 只有在需要的时候才被创建实例

因此对于多线程而言,无法保证线程安全。

为什么无法保证线程安全呢?

我们假设有多个线程1,线程2都需要使用这个单例对象。而恰巧,线程1在判断完instance==null后突然交换了cpu的使用权,变为线程2执行,由于instance仍然为null,那么线程2中就会创建这个Singleton的单例对象。之后线程1拿回cpu的使用权,而正好线程1之前暂停的位置就是判断instance是否为null之后,创建对象之前。这样线程1又会创建一个新的Singleton对象。

/**
* 懒汉式单例模式
* @author Xia
*/
public class Singleton2 { //指向自己实例的私有静态引用
private static Singleton2 instance ; //私有的构造方法
private Singleton2(){} //以自己实例为返回值的静态的公有方法,静态工厂方法
public static Singleton2 getInstance(){
// 被动创建,在真正需要使用时才去创建
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}

(3)线程安全的懒汉式单例——双重检查方式

上面我们提到,懒汉式的单例模式因为其创建是在需要的时候才new出来,中间可能会被打断,因此,需要用Synchronized关键字将对象锁定。

/**
* 线程安全的懒汉式单例模式
* @author Xia
*/
public class Singleton3 { //指向自己实例的私有静态引用
private static Singleton3 instance ; //私有的构造方法
private Singleton3(){} //以自己实例为返回值的静态的公有方法,静态工厂方法
public static Singleton3 getInstance(){
// 第一次检查
if (instance == null) {
//锁定该类对象
synchronized (Singleton3.class) {
//第二次检查
if (instance == null) {
instance = new Singleton3();
}
}
}
return instance;
}
}

java基础设计模式1——单例模式的更多相关文章

  1. Java与设计模式之单例模式(下) 安全的单例模式

          关于单例设计模式,<Java与设计模式之单例模式(上)六种实现方式>介绍了6种不同的单例模式,线程安全,本文介绍该如何保证单例模式最核心的作用——“实现该模式的类有且只有一个实 ...

  2. Java与设计模式之单例模式(上)六种实现方式

           阎宏博士在<JAVA与模式>中是这样描述单例模式的:作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类.      ...

  3. java基础---设计模式(1)

    出处:https://blog.csdn.net/zhangerqing/article/details/8194653 java的设计模式分为三大类 创建型模式: 工厂方法模式.抽象工厂模式.单例模 ...

  4. Java常见设计模式之单例模式

         1.何为单例模式? 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的 ...

  5. JAVA基础——设计模式之单列模式

    一:单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点. 单例设计模式的特点: 单例类只能 ...

  6. 《java常用设计模式之----单例模式》

    一.简介 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创 ...

  7. Java基础-设计模式之-代理模式Proxy

    代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理 ...

  8. 基于JAVA的设计模式之单例模式

    概念 于大二上学期面向对象C++期中考试中有这么道题:一个Computer有多个USB插口,那么意味着这台电脑可以插多个鼠标,但是无论你如何拔插多少个鼠标,桌面上的鼠标一直只显示一个,且多个硬件鼠标都 ...

  9. JAVA基础——设计模式之观察者模式

    观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependen ...

随机推荐

  1. MYSQL一次千万级连表查询优化

    概述:交代一下背景,这算是一次项目经验吧,属于公司一个已上线平台的功能,这算是离职人员挖下的坑,随着数据越来越多,原本的SQL查询变得越来越慢,用户体验特别差,因此SQL优化任务交到了我手上. 这个S ...

  2. js-ES6学习笔记-编程风格(1)

    1.ES6提出了两个新的声明变量的命令:let和const.其中,let完全可以取代var,因为两者语义相同,而且let没有副作用. 2.var命令存在变量提升效用,let命令没有这个问题.建议不再使 ...

  3. 清除input numer 点击样式

    input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; }

  4. Nginx的虚拟主机

    1.虚拟主机的概念和类型 1.1 概念: 所谓的虚拟主机,在web服务里面就是一个独立的网站站点,这个站点对应独立的域名(也有可能是IP或者端口),具有独立的程序和资源目录,可以独立的对外提供服务. ...

  5. 准备开发一个运行在Android上的JavaME模拟器

    在一个虚拟机A上运行另外一个虚拟机B看起来是挺不靠谱的一件事,在手机上运行某个虚拟机也不怎么靠谱.并且如果虚拟机A运行在手机上这个听起来就更不靠谱了.但是很多人就在做这样的事.比如在在手机上运行DOS ...

  6. BootStrap学习之栅格布局

    Bootstrap 提供了一套响应式.移动设备优先的流式栅格系统,随着屏幕或视口(viewport)尺寸的改变,系统会自动分为最多12列.它包含了易于使用的预定义类,还有强大的mixin用于生成更具语 ...

  7. 微信小程序开发1-入门知识准备

    注:一个物联网专业的学生狗,平时学习较多的是嵌入式编程方面的知识,最近可能是闲的蛋疼,想要研究研究客户端开发,对于网页,手机Android客户端从来没有接触过,因此所有东西都要从头来过,慢慢学习.不过 ...

  8. [Android] Service服务详解以及如何使service服务不被杀死

    排版上的细节有些不好看,主要是我用的MarkDown编辑器预览和这里的不一样,在那个上面的样式很舒服.这里要改的地方太多就不想改了,将就看吧.下次写的时候注意.还有看到错误给我提啊. 本文链接:htt ...

  9. myeclipse配置jboss

    一 相关软件准备 jdk1.6     Myeclipse    jboss 6.1 下载地址:http://www.jboss.org/jbossas/downloads/二 安装 下载完jboss ...

  10. java 版本压缩、解压缩zip

    import java.io.*; import java.util.*; import java.util.zip.ZipOutputStream; import java.util.zip.Zip ...