单例模式写法
2016-03-05 17:45
363 查看
1.懒汉,线程不安全
public class Singleton {
private static Singleton instance=null;
private Singleton(){
}
public static Singleton getInstance(){
if(instance==null)
instance=new Singleton();
return instance;
}
}
2.懒汉,线程安全
public class Singleton {
private static Singleton instance=null;
private Singleton(){
}
public synchronized static Singleton getInstance(){
if(instance==null)
instance=new Singleton();
return instance;
}
}
3.饿汉,线程安全。使用饿汉虽然简单线程安全,但一开始就实例化了Singleton,也许一开始根本用不上却要占用内存。
public class Singleton {
private static Singleton instance=new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
4.饿汉 第二种写法,采用静态构造代码块来实例化单例
public class Singleton {
private static Singleton instance=null;
static{
instance=new Singleton();
}
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
5.静态内部类,该方法与饿汉一样都是采用类加载机制来实现单例,不同的是加载Singleton类并不会导致instance初始化,而只有调用getInstance方法后,加载SingltonHolder类才初始化instance,从而达到和懒汉方式一样懒加载效果
public class Singleton {
private Singleton(){
}
public static Singleton getInstance(){
return SingltonHolder.instance;
}
private static class SingltonHolder{
private static final Singleton instance=new Singleton();
}
}
6.双重校验锁,这是第二种的升级版,细化加锁时机,避免不必要的加锁,从而提升效率,注意要加volatile关键字
public class Singleton {
/**注意要加上volatile
假设没有关键字volatile的情况下,两个线程A、B,都是第一次调用该单例方法,线程A先执行instance = new Instance(),
该构造方法是一个非原子操作,编译后生成多条字节码指令,由于JAVA的指令重排序,可能会先执行instance的赋值操作,该操作实际只
是在内存中开辟一片存储对象的区域后直接返回内存的引用,之后instance便不为空了,但是实际的初始化操作却还没有执行,如果就
在此时线程B进入,就会看到一个不为空的但是不完整(没有完成初始化)的Instance对象,所以需要加入volatile关键字,禁止指令重排序
优化,从而安全的实现单例。**/
private volatile static Singleton instance=null;
private Singleton(){
}
public static Singleton getInstance(){
if(instance==null){
synchronized (Singleton.class) {
if(instance==null)
instance=new Singleton();
}
}
return instance;
}
}
public class Singleton {
private static Singleton instance=null;
private Singleton(){
}
public static Singleton getInstance(){
if(instance==null)
instance=new Singleton();
return instance;
}
}
2.懒汉,线程安全
public class Singleton {
private static Singleton instance=null;
private Singleton(){
}
public synchronized static Singleton getInstance(){
if(instance==null)
instance=new Singleton();
return instance;
}
}
3.饿汉,线程安全。使用饿汉虽然简单线程安全,但一开始就实例化了Singleton,也许一开始根本用不上却要占用内存。
public class Singleton {
private static Singleton instance=new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
4.饿汉 第二种写法,采用静态构造代码块来实例化单例
public class Singleton {
private static Singleton instance=null;
static{
instance=new Singleton();
}
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
5.静态内部类,该方法与饿汉一样都是采用类加载机制来实现单例,不同的是加载Singleton类并不会导致instance初始化,而只有调用getInstance方法后,加载SingltonHolder类才初始化instance,从而达到和懒汉方式一样懒加载效果
public class Singleton {
private Singleton(){
}
public static Singleton getInstance(){
return SingltonHolder.instance;
}
private static class SingltonHolder{
private static final Singleton instance=new Singleton();
}
}
6.双重校验锁,这是第二种的升级版,细化加锁时机,避免不必要的加锁,从而提升效率,注意要加volatile关键字
public class Singleton {
/**注意要加上volatile
假设没有关键字volatile的情况下,两个线程A、B,都是第一次调用该单例方法,线程A先执行instance = new Instance(),
该构造方法是一个非原子操作,编译后生成多条字节码指令,由于JAVA的指令重排序,可能会先执行instance的赋值操作,该操作实际只
是在内存中开辟一片存储对象的区域后直接返回内存的引用,之后instance便不为空了,但是实际的初始化操作却还没有执行,如果就
在此时线程B进入,就会看到一个不为空的但是不完整(没有完成初始化)的Instance对象,所以需要加入volatile关键字,禁止指令重排序
优化,从而安全的实现单例。**/
private volatile static Singleton instance=null;
private Singleton(){
}
public static Singleton getInstance(){
if(instance==null){
synchronized (Singleton.class) {
if(instance==null)
instance=new Singleton();
}
}
return instance;
}
}
相关文章推荐
- performSelectorOnMainThread:withObject: waitUntilDone 参数解释
- Python IDLE或Python Shell不支持中文编码的解决方案
- 编程学习第二天,初识Python
- jquery高版本去除了 live的用法,用on代替
- 瀑布流
- 创建索引表
- 仿QQ实现从底部滑出选择框
- alarm and pause Functions
- DomainModel接收参数
- LeetCode : Regular Expression Matching [java]
- python 小练习之山寨版markdown格式txt文件转html文件
- Android多点触控基础
- 连连看完善
- leetcode:122. Best Time to Buy and Sell Stock II(java)解答
- CodeForces 158 B. Taxi(模拟)
- GUI相关学习资料
- 第24章 SEH结构化异常处理_异常处理及软件异常
- linux dmesg命令参数及用法详解(linux显示开机信息命令)
- 【EA教程】——ER图生成SQL脚本
- 神奇的位运算——进制转换问题(16转8)