java线程安全(单例模式)(转载)
原文链接:http://www.jameswxx.com/java/%E8%AF%B4%E8%AF%B4%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/
单例模式?多么简单!也许吧,可是要通过简单的现象,看到问题的本质,就比较难,知其然而不知其所以然,这种态度不好。
一:看看最简单的
public class SingleInstance{
private static instance=new SinleInstance();
public static SingleInstance getInstance(){
return instance;
}
}
这个很明了,也确实会返回唯一的实例,但是如果我永远都不会用到SingleInstance.getInstance(),instance这个对象却一直存在,占用了内存空间,浪费。
二:那就不先实例化
public class SingleInstance{
private static SingleInstance instance;
public static SingleInstance getInstance(){
if(instance==null){
instance=new SingleInstance();
}
return instance;
}
}
表面上,这个似乎是可行的。但是很显然,在多线程并发环境中,可能会创建两个instance,也有可能一个线程拿到的instance是一个不完整的实例。
三:好吧,那我加上同步总可以吧
public class SingleInstance{
private static SingleInstance instance;
public static synchronized SingleInstance getInstance(){
if(instance==null){
instance=new SingleInstance();
}
return instance;
}
}
这个虽然不会有内存上的浪费,但是有同步锁住了整个class,会降低系统的性能。按照数据结构的说法,就是一个提高了空间复杂度,一个提高了时间复杂度。
四:最佳实践
比较好的做法
public class SingleInstance {
private static class InstanceHolder {
public static final SingleInstance instance = new SingleInstance();
}
public static SingleInstance getInstance() {
return InstanceHolder.instance;
}
}
这种Holder做法保证了实例在用到的时候才会创建,而且创建的实例肯定是唯一的。
五:所谓的DCL
下面这种做法是广为流传的所谓DCL(双重检查锁定)做法,这是没有正确理解java内存模型造成的,只保证了创建实例的原子性,而没有解决共享资源的可见性。
public class SingleInstance{
private static SingleInstance instance;
public static SingleInstance getInstance(){
if(instance==null){
synchronized(SingleInstance.class){
if(instance==null){
instance=new SingleInstance();
}
}
}
return instance;
}
}
表面上看,这个似乎确实没有什么问题呢,其实还是有问题的,虽然概率比较小,要深刻的理解为什么,必须要对java内存模型比较熟悉。对于instance的创建,某个时刻某个线程拿到了同步锁,将instance创建了,并且及时写回了主存。但是对于另一个线程而言,它不能及时“看到”instance变量的最新值。它的instance可能是工作内存里的而不是主内存里的,甚至更为糟糕的情况是,instance是主内存的,可它的某些属性是工作内存的,这会导致程序发生莫名其妙不可捉摸的错误。在平台级框架里,这会造成系统在高并发环境下不稳定,甚至造成致命的错误 。
java线程安全(单例模式)(转载)的更多相关文章
- 50 道 Java 线程面试题(转载自牛客网)
下面是 Java 线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理 ...
- 深入了解java线程池(转载)
出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责 ...
- 【转载】 Java线程面试题 Top 50
Java线程面试题 Top 50 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员 的欢迎.大多数待遇丰厚的J ...
- Java线程面试题 Top 50 (转载)
转载自:http://www.cnblogs.com/dolphin0520/p/3958019.html 原文链接:http://www.importnew.com/12773.html 本文由 ...
- 【多线程】Java线程面试题 Top 50(转载)
Java线程面试题 Top 50 原文链接:http://www.importnew.com/12773.html 本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎 ...
- Java线程面试题 Top 50(转载)
原文链接:http://www.importnew.com/12773.html 本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎加入Java小组.转载请参见文章末尾的 ...
- 【转载】Java线程面试题 Top 50
Java线程面试题 Top 50 2014/08/21 | 分类: 基础技术 | 4 条评论 | 标签: 多线程, 面试题 分享到:140 本文由 ImportNew - 李 广 翻译自 javare ...
- JAVA线程安全总结(转载)
JAVA线程安全总结(一) JAVA线程安全总结(二) 最近想将java基础的一些东西都整理整理,写下来,这是对知识的总结,也是一种乐趣.已经拟好了提纲,大概分为这几个主题: java线程安全,jav ...
- (转载)JAVA线程池管理
平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...
- Java线程面试题 Top 50【转载】
不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎.大多数待遇丰厚的Java开发职位都要求开发者精通多线程 ...
随机推荐
- (C# 基础) 类访问修饰符
C# 中有5个权限修饰符,用于控制对对象的访问权限. 1. public: 访问不受限制. namespace, enum成员,interface成员 隐式的具有public 修饰符,不能在显式添 ...
- ansible使用3-playbook
playbook是ansible用于配置部署的语言.使用YAML格式. 示例 --- - hosts: webservers vars: http_port: 80 max_clients: 200 ...
- nginx的常用命令
一.nginx的解压安装 #tar xzvf nginx-1.6.0.tar.gz #cd nginx-1.6.0 #./configure --prefix=/home/weixin/loca ...
- Typora使用
Typora使用 1.介绍 typora是一款不错的软件. 1.1 基本使用 html js css python java vb 1.2 无序列表 a b c d e f 1.3 java代码 pu ...
- IOS GCD03-其他用法
#define global_queue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) #define main_queu ...
- .clone事件当你克隆的时候,DOM节点是克隆出来了,但是克隆出来的节点不能运行时事件 ...
解决办法如下在clone()里面加个参数true,即可完成事件的植入.即:.clone(true).clone( [ withDataAndEvents ], [ deepWithDataAndEve ...
- 【洛谷P3952】[NOIP2017]时间复杂度
时间复杂度 题目链接 对于 100%的数据:L≤100 . 很明显的模拟题 然而考试时还是爆炸了.. 调了一下午.. 蒟蒻表示不会离线操作.. 直接贴代码: #include<cstdio> ...
- Nginx配置文件详细解释
转自:https://www.cnblogs.com/knowledgesea/p/5175711.html 序言 Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开 ...
- ibator自动代码生成
首先,强烈推荐一篇文章,介绍的特详细 http://www.iteye.com/topic/821983 1. 插件安装 http://blog.csdn.net/rchm8519/article/d ...
- C# 变量与常量
变量表示存储位置,变量必须有确定的数据类型.C#的类型安全的含义之一就是确保变量的存储位置容纳着合适的类型.可以将C#中的变量分为静态变量,实例变量,传值参数,引用参数,输出参数,数组参数和本地变量共 ...