一、什么是单例模式

单例:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

单例模式是一种常用的软件设计模式之一,其目的是保证整个应用中只存在类的唯一个实例。

比如我们在系统启动时,需要加载一些公共的配置信息,对整个应用程序的整个生命周期中都可见且唯一,这时需要设计成单例模式。如:spring容器,session工厂,缓存,数据库连接池等等。

二、如何保证实例的唯一

1)防止外部初始化

2)由类本身进行实例化

3)保证实例化一次

4)对外提供获取实例的方法

5)线程安全

三、几种单利模式的比较

(1)饿汉式

“因为饿,所以要立即吃饭,刻不容缓”,在定义类的静态私有变量同时进行实例化。

public class Singleton {

private static final Singleton singleton = new Singleton();

private Singleton() {

}

public static Singleton getInstance() {

return singleton;

}

}

①声明静态私有类变量,且立即实例化,保证实例化一次

②私有构造,防止外部实例化(通过反射是可以实例化的,不考虑此种情况)

③提供public的getInstance()方法供外部获取单例实例

好处:线程安全;获取实例速度快 缺点:类加载即初始化实例,内存浪费

(2)懒汉式

“这个人比较懒,等用着你的时候才去实例化”,延迟加载。

public class Singleton {

private static Singleton singleton = null;

private Singleton() {

}

public static Singleton getInstance() {

if (singleton == null) {

singleton = new Singleton();

}

return singleton;

}

}

优点:在获取实例的方法中,进行实例的初始化,节省系统资源

缺点:①如果获取实例时,初始化工作较多,加载速度会变慢,影响系统系能

②每次获取实例都要进行非空检查,系统开销大

③非线程安全,当多个线程同时访问getInstance()时,可能会产生多个实例

接下来对它进行线程安全改造:

1)同步锁

public synchronized static Singleton getInstance() {

if (singleton == null) {

singleton = new Singleton();

}

return singleton;

}

优点:线程安全,缺点:每次获取实例都要加锁,耗费资源,其实只要实例已经生成,以后获取就不需要再锁了

2)双重检查锁

public static Singleton getInstance() {

if (singleton == null) {

synchronized (Singleton.class) {

if (singleton == null) {

singleton = new Singleton();

}

}

}

return singleton;

}

优点:线程安全,进行双重检查,保证只在实例未初始化前进行同步,效率高 缺点:还是实例非空判断,耗费一定资源

 

3)静态内部类

public class Singleton {

private Singleton() {

}

private static class SingletonHolder {

private static final Singleton singleton = new Singleton();

}

public static Singleton getInstance() {

return SingletonHolder.singleton;

}

}

优点:既避免了同步带来的性能损耗,又能够延迟加载

 

(3)枚举

public enum Singleton {

INSTANCE;

public void init() {

System.out.println("资源初始化。。。");

}

}

天然线程安全,可防止反射生成实例。

四、单例模式的优缺点

优点:该类只存在一个实例,节省系统资源;对于需要频繁创建销毁的对象,使用单例模式可以提高系统性能。

缺点:不能外部实例化(new),调用人员不清楚调用哪个方法获取实例时会感到迷惑,尤其当看不到源代码时。

关注老姜谈技术,微信号:helojava,或者扫描下面二维码。


每日一帖,技术鸡汤。

java单例模式的实现方式的更多相关文章

  1. Java单例模式 多种实现方式

    一:通过静态私有成员实现单例模式 (1):私有化构造函数 (2):new静态实例属性对象,加锁. 单例类: package SinglePag; /* * 构造函数私有化,结合锁+静态的概念 实现单例 ...

  2. Java单例模式(转载)

    原文地址:1:http://www.cnblogs.com/hupp/p/4487521; 2:http://cantellow.javaeye.com/blog/838473 先罗列五种单例模式的实 ...

  3. 深入Java单例模式(转)

    深入Java单例模式 源自 http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容 ...

  4. java单例模式的心得

    由于设计模式对于java高级开发人员来说是非常重要的,网上也有很多关于设计模式的文章,博客等.所以,首先我对相对简单的单例模式做一个简单的总结. 一.实现方式 单例模式的实现方式有3种,分别是饿汉式, ...

  5. Java 单例模式的七种写法

    Java 单例模式的七种写法 第一种(懒汉,线程不安全) public class Singleton { private static Singleton instance; private Sin ...

  6. Java 单例模式探讨

    以下是我再次研究单例(Java 单例模式缺点)时在网上收集的资料,相信你们看完就对单例完全掌握了 Java单例模式应该是看起来以及用起来简单的一种设计模式,但是就实现方式以及原理来说,也并不浅显哦. ...

  7. 单例模式:Java单例模式的几种写法及它们的优缺点

    总结下Java单例模式的几种写法: 1. 饿汉式 public class Singleton { private static Singleton instance = new Singleton( ...

  8. 9种Java单例模式详解(推荐)

    单例模式的特点 一个类只允许产生一个实例化对象. 单例类构造方法私有化,不允许外部创建对象. 单例类向外提供静态方法,调用方法返回内部创建的实例化对象.  懒汉式(线程不安全) 其主要表现在单例类在外 ...

  9. 用java单例模式实现面板切换

    1.首先介绍一下什么是单例模式: java单例模式是一种常见的设计模式,那么我们先看看懒汉模式: public class Singleton_ { //设为私有方法,防止被外部类引用或实例 priv ...

随机推荐

  1. Entity Framework 延伸系列目录

    1.采用MiniProfiler监控EF与.NET MVC项目 2.采用EntityFramework.Extended 对EF进行扩展 3.EntityFramework执行存储过程中遇到的那些坑 ...

  2. Android 调用百度地图API

    一.到 百度地图开发平台下载SDK http://lbsyun.baidu.com/index.php?title=androidsdk/sdkandev-download 1.点击自定义下载 2.下 ...

  3. 嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比

    C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(i ...

  4. 图解Spark API

    初识spark,需要对其API有熟悉的了解才能方便开发上层应用.本文用图形的方式直观表达相关API的工作特点,并提供了解新的API接口使用的方法.例子代码全部使用python实现. 1. 数据源准备 ...

  5. Linux CentOS7通过yum命令安装Mono(尝先安装模式)

    前言 经过尝试网上各种安装mono的技术贴,这个安装过程经历了大约2周,尝试了各个版本,几目前博客所描述的所有安装方式.以下内容的安装方式可以为你尝试不同版本的mono.并非正式环境安装标准方式安装. ...

  6. .NET跨平台:在Ubuntu上用自己编译的dnx运行ASP.NET 5示例程序

    在 Linux Ubuntu 上成功编译 dnx 之后,会在 artifacts/build/ 文件夹中生成 dnx-coreclr-linux-x64/ 与 dnx-mono/ 这2个文件夹,前者是 ...

  7. Johnson 全源最短路径算法

    解决单源最短路径问题(Single Source Shortest Paths Problem)的算法包括: Dijkstra 单源最短路径算法:时间复杂度为 O(E + VlogV),要求权值非负: ...

  8. RavenDB官网文档翻译系列第一

    本系列文章主要翻译自RavenDB官方文档,有些地方做了删减,有些内容整合在一起.欢迎有需要的朋友阅读.毕竟还是中文读起来更亲切吗.下面进入正题. 起航 获取RavenDB RavenDB可以通过Nu ...

  9. 在多线程编程中lock(string){...}隐藏的机关

    常见误用场景:在订单支付环节中,为了防止用户不小心多次点击支付按钮而导致的订单重复支付问题,我们用 lock(订单号) 来保证对该订单的操作同时只允许一个线程执行. 这样的想法很好,至少比 lock( ...

  10. ABP(现代ASP.NET样板开发框架)系列之13、ABP领域层——数据过滤器(Data filters)

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之13.ABP领域层——数据过滤器(Data filters) ABP是“ASP.NET Boilerplate P ...