单例模式的线程安全性问题浅析
来源:互联网 发布:华方 线切割编程 编辑:程序博客网 时间:2024/05/21 10:54
单例的线程安全问题关注
最近面试工作时经常会被问到单例会带来什么问题?单例是否是安全的?我想如果是单线程就可以放心大胆的说是的,但是
如果多个线程同时调用这个实例,就会有线程安全的问题
单例一般用在什么地方?
单例的目的是为了保证运行时只有唯一的一个实例,最常用的地方比如拿到数据库的连接,或者Spring的中创建BeanFactory操作,而这些操作都是调用他们的方法来执行某个特定的动作。
首先先来认识下两种模式: 恶汉式 懒汉式
public class MyFactory { // //饿汉式 立即创建// private static MyFactory instance = new MyFactory();
// private MyFactory(){};// public static MyFactory getInstance(){// return instance;// } //懒汉式用到的时候在创建,不用就不创建(有线程安全问题) private static MyFactory instance = null;
private MyFactory(){}; public static MyFactory getInstance(){ instance = new MyFactory();return instance; } }
下面总结一下解决线程安全的几种方式:
方法一:在MyFactory 中加入了一个私有静态内部类instanceHolder ,对外提供的接口是 getInstance()方法,也就是只有在MyFactory.getInstance()的时候,instance对象才会被创建,,没有使用同步。保证了只有一个实例,还同时具有了Lazy的特性
public class MyFactory { private static class instanceHolder { public static MyFactory instance = new MyFactory(); } private MyFactory(){}; public static MyFactory getInstance() { return MyFactory.instanceHolder.instance; } }
测试代码
import static org.junit.Assert.*;import org.junit.Test;public class MyFactoryTest { @Test public void testGetResource() { MyFactory mf1 = MyFactory.getInstance(); MyFactory mf2 = MyFactory.getInstance(); System.out.println(mf1 != null);//true System.out.println(mf1 == mf2);//true }}
方式二:(懒汉式)
这种方式也没有使用同步,并且确保了调用static getInstance()方法时才创建MyFactory的引用,
private static MyFactory instance = new MyFactory();
private MyFactory(){};
public static MyFactory getInstance() { return instance; }
测试代码:同方法一
方式三:使用synchronized ,通常会锁定整个方法的是比较耗费资源的,实际会产生多线程访问问题的是这一句代码instance = new MyFactory();
为了减少资源的消耗,只锁这一句就行了, 两个线程并发地进入第一次判断instance是否为空的if 语句内部,一个线程获得了锁执行new操作,另一个线程被阻塞,
当第一个线程执行完毕之后,第二个线程如果直接进行new操作也是不安全的。为了避免第二次new操作,添加第二次条件判断,既二次检查
private static MyFactory instance;
private MyFactory(){}; public static MyFactory getInstance(){ if(instance == null){ synchronized (MyFactory.class) { if(instance == null){ instance = new MyFactory(); } } } return instance; }
测试代码 同方法一
- 单例模式的线程安全性问题浅析
- 模式+线程安全性 -- Java单例对象同步问题探讨
- 单例模式的写法和线程安全性的讨论
- 单例模式与线程安全问题浅析
- 如何保证单例模式在多线程中的线程安全性
- 浅析HashMap与ConcurrentHashMap的线程安全性
- 浅析HashMap与ConcurrentHashMap的线程安全性
- 浅析单例模式
- 浅析单例模式
- 单例模式浅析
- 单例模式浅析
- IConfigurationSectionHandler的线程安全性问题
- servlet的线程安全性问题
- c++单例模式在多线程环境下的安全性
- 单例模式在多线程下的安全性
- 解决多线程单例模式的线程不安全问题
- 单例模式 下的线程锁问题
- 单例中的线程不安全性
- 递归
- cv1378 选课(树)
- ftrace学习
- Web学习日记17--------继续angularjs实现京东购物车
- 自己动手写操作系统:2.C语言文件操作,制作系统引导程序
- 单例模式的线程安全性问题浅析
- TENSORFLOW1.0运行之前版本代码报错解决
- 矩阵幂之和(矩阵乘法)
- 剑指offer:丑数
- TensorFlow不同版本引起的错误
- Android的5个进程等级
- Go语言学习笔记(一)程序结构
- 13-SpringBoot——Spring MVC基础-高级配置-文件上传
- [ubuntu] 安装 ubuntu 和 windows 双系统后时间不同步问题解决