Java线程和多线程(五)——单例类中的线程安全
单例模式是最广泛使用的创建模式之一。在现实世界之中,诸如Databae的连接或者是企业信息系统(EIS)等,通常其创建都是受到限制的,应该尽量复用已存在对象而不是频繁创建销毁。为了达到这个目的,开发者通常会通过实现单例模式来创建一个wrapper类,来封装资源,限制其运行时所创建对象的个数。
单例中的线程安全
总的来说,开发者一般会按照如下的方式来创建单例的类:
- 使用私有构造函数来避免其它外部引用通过new的方式来创建新的对象引用。
- 声明一个该类的私有静态变量为实例。
- 提供一个公有的静态方法来返回单例的实例。如果实例还没有初始化的话,就将其初始化后再返回实例。
通过上面的步骤,我写了一个如下的单例类:
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线程和多线程(五)——单例类中的线程安全的更多相关文章
- c++:自己动手实现线程安全的c++单例类
前段时间使用c++做项目开发,需要根据根据配置文件路径加载全局配置文件,并对外提供唯一访问点.面对这样一个需求,自然的就想到了使用单例模式来创建一个单例配置对象,供外部调用.一开始想使用boost中自 ...
- java设计模式--解决单例设计模式中懒汉式线程安全问题
首先写个单例,懒汉模式: public class SingleDemo { private static SingleDemo s = null; private SingleDemo(){} pu ...
- C# 语法五 单例类、单例模式
1.优点 只有一个实例 2.缺点 a)这个实例不能随时释放掉,占用资源. b)每次使用,都要判断是否为空,增加消耗 3.适用场景 只能有一个实例的业务场景,例如:数据库连接对象(每次连接都是同一个连接 ...
- iOS中编写单例类的心得
单例 1.认识过的单例类有哪些: NSUserDefaults.NSNotificationCenter.NSFileManager.UIApplication 2.单例类 单例类某个类在代码编写时使 ...
- 单例类singleton自动释放
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- [转]单例模式——C++实现自动释放单例类的实例
[转]单例模式——C++实现自动释放单例类的实例 http://www.cnblogs.com/wxxweb/archive/2011/04/15/2017088.html http://blog.s ...
- [iOS]封装单例类
[iOS]封装单例类 今天在学习iOS的SQLite开发,发现在需要使用SQLite的每个视图中,都需要对数据库进行打开或关闭,觉得挺麻烦的:于是在想能否写个单例类对这些操作进行封(因以前一直在使用D ...
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...
- Java 多线程之单例设计模式
转载:https://segmentfault.com/a/1190000007504892 概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉 ...
随机推荐
- 【起航计划 011】2015 起航计划 Android APIDemo的魔鬼步伐 10 App->Activity->Reorder Activities 后退栈 Intent FLAG
Reorder Activities 示例有四个相关的Activitives: ReorderOnLaunch, ReorderTwo,ReorderThree, ReorderFour.其中Reor ...
- EF--Model First
Model First先设计Model对象,再由对象生成数据库. 1.新建控制台项目,名称ModelFirst,确定. 2.点击选中项目,右键-->添加-->新建项目--选择数据模板--& ...
- springboot/springmvc转换器
常用的转换器 String转Date转换器(用于接受日期参数自动转换成Date类型便于后台数据处理) /** * 全局handler前日期统一处理 * @author zhanghang * @dat ...
- 微信小程序加载本地图片方法
目录结构如下,只要图片按正确的方式放入小程序的开发工具的项目中,即可在wxml文件中用内联样式或者image标签都可以引用本地的图片. 步骤一:微信开发工具 打开项目 步骤二:新建个文件夹(放项目的一 ...
- Linux常用命令之文件和目录操作命令
以下是linux操作系统常用的文件和目录操作命令: cd /home 进入 '/ home' 目录' cd .. 返回上一级目录 cd ../.. 返回上两级目录 cd 进入个人的主目录 cd ...
- IOS GCD03-其他用法
#define global_queue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) #define main_queu ...
- 【转】关于Eclipse创建Android项目时,会多出一个appcompat_v7的问题
问题描述: 使用eclipse创建一个Android项目时,发现project列表中会多创建出一个appcompat_v7项目,再创建一个Android项目时,又会再多出一个appcompat_v7_ ...
- 2018.7.8 xmlhttp.readyState==4 && xmlhttp.status==200是什么意思
在做DOM模型的XML实验的时候遇到了问题 代码实例: xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && ...
- 第50章 读写内部FLASH—零死角玩转STM32-F429系列
第50章 读写内部FLASH 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...
- 121. Best Time to Buy and Sell Stock——Leetcode
Say you have an array for which the ith element is the price of a given stock on day i. If you were ...