单例模式是最广泛使用的创建模式之一。在现实世界之中,诸如Databae的连接或者是企业信息系统(EIS)等,通常其创建都是受到限制的,应该尽量复用已存在对象而不是频繁创建销毁。为了达到这个目的,开发者通常会通过实现单例模式来创建一个wrapper类,来封装资源,限制其运行时所创建对象的个数。

单例中的线程安全

总的来说,开发者一般会按照如下的方式来创建单例的类:

  1. 使用私有构造函数来避免其它外部引用通过new的方式来创建新的对象引用。
  2. 声明一个该类的私有静态变量为实例。
  3. 提供一个公有的静态方法来返回单例的实例。如果实例还没有初始化的话,就将其初始化后再返回实例。

通过上面的步骤,我写了一个如下的单例类:

package com.sapphire.designpatterns;

public class ASingleton {

    private static ASingleton instance = null;

    private ASingleton() {
} public static ASingleton getInstance() {
if (instance == null) {
instance = new ASingleton();
}
return instance;
}
}

在上面的代码中,getInstance()方法不是线程安全的。多线程可以在同一时间访问这个方法,而在最开始的少数线程中,实例没有初始化的时候,多线程可以进入到if代码块来创建多个实例,就破坏了单例模式。

通常来说,有三种方式来让我们保证单例模式的线程安全。

在class加载的时候就创建实例变量

这种实现方式有如下优点:

  • 不需要同步即可实现线程安全
  • 容易实现

但是也有一些缺点:

  • 过早的创建了资源,但是应用可能并不会使用这个资源,造成了资源浪费
  • 调用方式无法传入任何参数的,所以我们无法复用这个类。举例来说,如果我们希望有一个单例类能够处理所有的数据库连接信息,并希望能够传入一些数据库信息的话,我们就无法复用这个单例类了。

同步getInstance()方法

这种方法有如下优点:

  • 保证了线程安全
  • 调用方可以传入任何参数
  • 可以保证延迟初始化

当然这种方法也有一些缺点:

  • 因为使用了同步方法,会锁定资源,令所有客户端的请求会优先请求锁,从而降低了性能
  • 包含了很多非必要的同步,因为一旦实例创建完成,同步就只是浪费了性能而没有任何作用了

在if代码块中使用同步代码块

优点:

  • 保证了线程的安全
  • 调用方可以传递参数
  • 保证了延迟初始化
  • 最小化了同步负载,仅仅在最开始的几个线程请求的时候进行同步操作

淡然也有一定的缺点

  • 需要额外的if条件判断

从三种方法来判断,第三种方式应该是最佳的方式来实现同步了,代码大体如下:

package com.sapphire.designpatterns;

public class ASingleton{

    private static ASingleton instance= null;
private static Object mutex= new Object();
private ASingleton(){
} public static ASingleton getInstance(){
if(instance==null){
synchronized (mutex){
if(instance==null) instance= new ASingleton();
}
}
return instance;
}
}

注意,String对象非常不适合来作为同步的锁,因为String可能是复用的对象,锁定String很容易产生死锁切很难发现,所以这里使用的是Object对象来作为同步锁。

Java线程和多线程(五)——单例类中的线程安全的更多相关文章

  1. c++:自己动手实现线程安全的c++单例类

    前段时间使用c++做项目开发,需要根据根据配置文件路径加载全局配置文件,并对外提供唯一访问点.面对这样一个需求,自然的就想到了使用单例模式来创建一个单例配置对象,供外部调用.一开始想使用boost中自 ...

  2. java设计模式--解决单例设计模式中懒汉式线程安全问题

    首先写个单例,懒汉模式: public class SingleDemo { private static SingleDemo s = null; private SingleDemo(){} pu ...

  3. C# 语法五 单例类、单例模式

    1.优点 只有一个实例 2.缺点 a)这个实例不能随时释放掉,占用资源. b)每次使用,都要判断是否为空,增加消耗 3.适用场景 只能有一个实例的业务场景,例如:数据库连接对象(每次连接都是同一个连接 ...

  4. iOS中编写单例类的心得

    单例 1.认识过的单例类有哪些: NSUserDefaults.NSNotificationCenter.NSFileManager.UIApplication 2.单例类 单例类某个类在代码编写时使 ...

  5. 单例类singleton自动释放

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  6. [转]单例模式——C++实现自动释放单例类的实例

    [转]单例模式——C++实现自动释放单例类的实例 http://www.cnblogs.com/wxxweb/archive/2011/04/15/2017088.html http://blog.s ...

  7. [iOS]封装单例类

    [iOS]封装单例类 今天在学习iOS的SQLite开发,发现在需要使用SQLite的每个视图中,都需要对数据库进行打开或关闭,觉得挺麻烦的:于是在想能否写个单例类对这些操作进行封(因以前一直在使用D ...

  8. JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

    JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...

  9. Java 多线程之单例设计模式

    转载:https://segmentfault.com/a/1190000007504892 概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉 ...

随机推荐

  1. PCB仿真软件与电磁场求解器的算法

    1. 简介 目前商业化的PCB仿真软件主要有: Cadence公司的Sigrity.Ansys公司的SIwave/HFSS.CST公司的CST.Mentor公司的HyperLynx.Polor公司的S ...

  2. 带来全新的网络格局---html5

    自从HTML5诞生之后,就是开始建立了一个标准的原则,那就是所有的技术它必须是面向开放,并不能有专利的一个存在,在整个期间Opera捐献了css技术,而google的话则是给开发者提供了视频的webM ...

  3. Jerry Wang诚邀广大SAP同仁免费加入我的知识星球,共同探讨SAP技术问题

    大家知道Jerry Wang有一个微信公众号"汪子熙",2017年12月27日,Jerry的这个公众号发布了第一篇文章.到今天2018年10月底为止,正好十个月. 在这10个月的时 ...

  4. cs231n 17-18 assignment2 出现 No module named 'past' 解决方法

    解决方法: pip install future

  5. 微信小程序加载本地图片方法

    目录结构如下,只要图片按正确的方式放入小程序的开发工具的项目中,即可在wxml文件中用内联样式或者image标签都可以引用本地的图片. 步骤一:微信开发工具 打开项目 步骤二:新建个文件夹(放项目的一 ...

  6. Nginx+Tomcat+memcached高可用会话保持

    Nginx+Tomcat+memcached高可用会话保持 文章来源dyc2005   一.概述 之前文章已经描述了企业高可用负载相关的架构及实现,其中常用的nginx或haproxy,LVS结合ke ...

  7. 2017.10.18 微机原理与接口----汇编语言语法和DOS功能调用

    4.1 汇编语言中的基本数据 ·标识符 ·常数 ·变量具有三个属性: (1)段地址(SEG):变量所在段的段地址 (2)偏移地址(OFFSET):变量所在段内的偏移地址 (3)类型(TYPE):每个变 ...

  8. Spring boot 集成 Swagger

    添加依赖包 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swa ...

  9. linux flushing file system caches

    We may drop the file system caches on Linux to free up memory for applications. Kernels 2.6.16 and n ...

  10. How good are detection proposals, really?

    How good are detection proposals, really? J. Hosang, R. Benenson, B. Schiele Oral at BMVC 2014 http: ...