单例模式
2015-08-25 22:22
302 查看
饿汉式(常用)
public class EagerSingleton {
private static EagerSingleton instance = new EagerSingleton();
/**
* 私有默认构造子
*/
private EagerSingleton(){}
/**
* 静态工厂方法
*/
public static EagerSingleton getInstance(){
return instance;
}
}
懒汉式
public class LazySingleton {
private static LazySingleton instance = null;
/**
* 私有默认构造子
*/
private LazySingleton(){}
/**
* 静态工厂方法
*/
public static synchronized LazySingleton getInstance(){
if(instance == null){
instance = new LazySingleton();
}
return instance;
}
}
简单总结一下这样的写法:
提供一个全局静态的
延迟Singleton的实例化,节省资源(所谓的懒汉式).
缺点是线程不安全.当多个线程同时进入
饿汉式与之前提到的懒汉式不同,它在我们调用getIns之前就实例化了(在类加载的时候就实例化了),所以不是一个懒加载,这样就有几个缺点:
延长了类加载时间
如果没用到这个类,就浪费了资源(加载了但是没用它)
不能传递参数(很显然适用的场景会减少)
接下去介绍一种更优秀的,线程安全的单例写法---双重检查锁模式(double check locking pattern)
注意这里的ins用了
因为执行
给ins分配内存
调用构造函数来初始化成员变量(可能会很久)
将ins对象指向分配的内存空间(执行完这步 ins才不为null)
静态内部类原理同上,另外虽然它看上去有点恶汉式,但是与之前的恶汉有点不同,它在类
Java中也推荐这个方式)
例子:
推荐双重检查锁和静态内部类
public class EagerSingleton {
private static EagerSingleton instance = new EagerSingleton();
/**
* 私有默认构造子
*/
private EagerSingleton(){}
/**
* 静态工厂方法
*/
public static EagerSingleton getInstance(){
return instance;
}
}
懒汉式
public class LazySingleton {
private static LazySingleton instance = null;
/**
* 私有默认构造子
*/
private LazySingleton(){}
/**
* 静态工厂方法
*/
public static synchronized LazySingleton getInstance(){
if(instance == null){
instance = new LazySingleton();
}
return instance;
}
}
简单总结一下这样的写法:
提供一个全局静态的
getIns方法,使得易于使用.
延迟Singleton的实例化,节省资源(所谓的懒汉式).
缺点是线程不安全.当多个线程同时进入
if (null == ins) {}的时候就会创建多个实例.
饿汉式与之前提到的懒汉式不同,它在我们调用getIns之前就实例化了(在类加载的时候就实例化了),所以不是一个懒加载,这样就有几个缺点:
延长了类加载时间
如果没用到这个类,就浪费了资源(加载了但是没用它)
不能传递参数(很显然适用的场景会减少)
性能进阶
接下去介绍一种更优秀的,线程安全的单例写法---双重检查锁模式(double check locking pattern)public class DoubleCheck { private volatile static DoubleCheck ins; private DoubleCheck() {} public static DoubleCheck getIns() { if (null==ins){ //检查 synchronized (DoubleCheck.class){ if (null == ins) { //又检查一次 ins = new DoubleCheck(); } } } return ins; } }
注意这里的ins用了
volatile关键字来修饰,为什么呢?
因为执行
ins = new DoubleCheck()做了很多事情:
给ins分配内存
调用构造函数来初始化成员变量(可能会很久)
将ins对象指向分配的内存空间(执行完这步 ins才不为null)
静态内部类
静态内部类原理同上,另外虽然它看上去有点恶汉式,但是与之前的恶汉有点不同,它在类Singleton加载完毕后并没有实例化,而是当调用
getIns去加载Holder的时候才会实例化,静态内部类的方式把实例化延迟到了内部类的加载中去了!所以它比饿汉式更优秀!(偷偷告诉你Effective
Java中也推荐这个方式)
例子:
public class Singleton { private static class Holder{ private static final Singleton INSTANCE = new Singleton(); } public static Singleton getIns(){ return Holder.INSTANCE; } }
推荐双重检查锁和静态内部类
相关文章推荐
- xilinx zynq vdma 记录
- linux命令详解(5):mkdir
- Windows update 失败的解决方案
- HDU 4111 Alice and Bob (博弈)
- 简述Session 、Cookie、cache 区别
- maven jdk win10
- Java 解决 Unsupported major.minor version 52.0
- Android Canvas绘图详解
- [2015年][7月27~8月26]
- fgets()与gets()的区别
- C#打印服务
- 2015-8-25-关于后端的知识以及常用函数整理
- 计算机网络系统--常用DOS命令
- 【LeetCode】268. Missing Number
- 一些奇怪的错误
- 【Leetcode】Rain trapping
- 关于战网BLZBNTBTS0000005D的解决方法
- 静态方法和静态代码块
- 如何用Java回调和线程实现异步调用
- VS2010 C/S模式winForm打包部署.详细! .