论线程安全的单例模式
2016-07-19 22:20
393 查看
一 懒汉式
第一种 (非线程安全)
public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
第二种( 双重检查 ,性能中等)
private static volatile TestSingleton instance = null;
public static TestSingleton getInstance() {
if (instance == null) {
synchronized (TestSingleton.class) {
if (singleton == null) {
singleton = new TestSingleton();
}
}
}
return instance;
}
第三种 (静态内部类 , 性能最好,利用了classload的时候只会有一个线程去加载和访问这个对象的原理,避免了多线程的问题)
二 饿汉式
天生线程安全,所以无需要多做介绍。
最后:注意
在懒汉式的第二种方法里。单列对象被声明为volatile。原因如下:
假设没有关键字volatile的情况下,两个线程A、B,都是第一次调用该单例方法,线程A先执行instance
= new Instance(),该构造方法是一个非原子操作,
编译后生成多条字节码指令,由于JAVA的指令重排序,可能会先执行instance的赋值操作,该操作实际只是在内存中开辟一片存储对象的区域后直接返回内存的引用,
之后instance便不为空了,但是实际的初始化操作却还没有执行,如果就在此时线程B进入,就会看到一个不为空的但是不完整(没有完成初始化)的Instance对象,
所以需要加入volatile关键字,禁止指令重排序优化,从而安全的实现单例。
第一种 (非线程安全)
public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
第二种( 双重检查 ,性能中等)
private static volatile TestSingleton instance = null;
public static TestSingleton getInstance() {
if (instance == null) {
synchronized (TestSingleton.class) {
if (singleton == null) {
singleton = new TestSingleton();
}
}
}
return instance;
}
第三种 (静态内部类 , 性能最好,利用了classload的时候只会有一个线程去加载和访问这个对象的原理,避免了多线程的问题)
public class Singleton { private static class LazyHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return LazyHolder.INSTANCE; } }
二 饿汉式
public class Singleton1 { private Singleton1() {} private static final Singleton1 single = new Singleton1(); //静态工厂方法 public static Singleton1 getInstance() { return single; } }饿汉
天生线程安全,所以无需要多做介绍。
最后:注意
在懒汉式的第二种方法里。单列对象被声明为volatile。原因如下:
假设没有关键字volatile的情况下,两个线程A、B,都是第一次调用该单例方法,线程A先执行instance
= new Instance(),该构造方法是一个非原子操作,
编译后生成多条字节码指令,由于JAVA的指令重排序,可能会先执行instance的赋值操作,该操作实际只是在内存中开辟一片存储对象的区域后直接返回内存的引用,
之后instance便不为空了,但是实际的初始化操作却还没有执行,如果就在此时线程B进入,就会看到一个不为空的但是不完整(没有完成初始化)的Instance对象,
所以需要加入volatile关键字,禁止指令重排序优化,从而安全的实现单例。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python3写爬虫(四)多线程实现数据爬取
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序