常见单例设计模式的对比分析
2015-11-27 15:28
281 查看
单例设计模式
//饿汉式
public class Singleton01 {
//1.私有的静态的变量
privatestatic Singleton01 instance=new Singleton01();
//2.私有的构造器
privateSingleton01(){}
//3.共有的get()方法
publicstatic Singleton01 getInstance(){
returninstance;
}
}
//懒汉式
public class Singleton02 {
//1.私有的静态的变量
privatestatic Singleton02 instance;
//2.私有的构造器
privateSingleton02(){
if(instance!=null){
thrownew RuntimeException();//防止反射和反序列化漏洞
}
}
//3.公有get方法
publicstatic synchronized Singleton02 getInstance(){
//要防止线程同步
if(null==instance){
returnnew Singleton02();//延时加载
}
returninstance;
}
}
//静态内部类,兼备了高效调用和延迟加载的优势
public class Singleton03 {
//外部类没有static属性,则不会像饿汉式那样立即加载对象
privatestatic class SingletonClassInstance{
privatestatic final Singleton03 instance=new Singleton03();
}
//只有真正调用getInstance(),才会加载静态内部类。加载类时是线程安全的。instance是static final类型
//保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性
publicstatic Singleton03 getInstance(){
returnSingletonClassInstance.instance;
}
privateSingleton03(){}
}
1. 饿汉式是天然的线程安全的,而且没有反射和反序列化的漏洞,但是没有延迟加载的优势。饿汉式之所以是天然的线程安全,是因为:
一个字节码文件被加载到内存会经历以下过程:
1、链接(1、验证2、准备3、解析)
2、初始化
3、使用
4、卸载
初始化是执行类构造器<clinit>()方法的过程。类构造器<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static)中的语句合并产生的。在这个过程中instance已经被实例化了。并且虚拟机JVM会保证一个类的<clinit>()方法在多线程的环境中被正确加锁和同步。因此他是天然线程安全的。
2. 懒汉式具有延迟加载的优势,但是一般的懒汉式线程都不安全,而且有反射和反序列化的的漏洞,如上所写便可防止反射反序列化的漏洞,而且线程安全,但是这样一来调用效率变得很低。
3. 静态内部类具有线程安全、延迟加载的优势目前也比较常用到
//饿汉式
public class Singleton01 {
//1.私有的静态的变量
privatestatic Singleton01 instance=new Singleton01();
//2.私有的构造器
privateSingleton01(){}
//3.共有的get()方法
publicstatic Singleton01 getInstance(){
returninstance;
}
}
//懒汉式
public class Singleton02 {
//1.私有的静态的变量
privatestatic Singleton02 instance;
//2.私有的构造器
privateSingleton02(){
if(instance!=null){
thrownew RuntimeException();//防止反射和反序列化漏洞
}
}
//3.公有get方法
publicstatic synchronized Singleton02 getInstance(){
//要防止线程同步
if(null==instance){
returnnew Singleton02();//延时加载
}
returninstance;
}
}
//静态内部类,兼备了高效调用和延迟加载的优势
public class Singleton03 {
//外部类没有static属性,则不会像饿汉式那样立即加载对象
privatestatic class SingletonClassInstance{
privatestatic final Singleton03 instance=new Singleton03();
}
//只有真正调用getInstance(),才会加载静态内部类。加载类时是线程安全的。instance是static final类型
//保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性
publicstatic Singleton03 getInstance(){
returnSingletonClassInstance.instance;
}
privateSingleton03(){}
}
1. 饿汉式是天然的线程安全的,而且没有反射和反序列化的漏洞,但是没有延迟加载的优势。饿汉式之所以是天然的线程安全,是因为:
一个字节码文件被加载到内存会经历以下过程:
1、链接(1、验证2、准备3、解析)
2、初始化
3、使用
4、卸载
初始化是执行类构造器<clinit>()方法的过程。类构造器<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static)中的语句合并产生的。在这个过程中instance已经被实例化了。并且虚拟机JVM会保证一个类的<clinit>()方法在多线程的环境中被正确加锁和同步。因此他是天然线程安全的。
2. 懒汉式具有延迟加载的优势,但是一般的懒汉式线程都不安全,而且有反射和反序列化的的漏洞,如上所写便可防止反射反序列化的漏洞,而且线程安全,但是这样一来调用效率变得很低。
3. 静态内部类具有线程安全、延迟加载的优势目前也比较常用到
相关文章推荐
- spring中的事物管理的5种实现方式的总结
- 【.NET】Cookie操作类
- redis 本机链接服务端命令
- 报表设计中参数、脚本的使用以及生成系统时间
- 机器学习实战k-近邻算法(kNN)应用之改进婚恋网站配对效果代码解
- 抽象类和接口的应用
- eclipse导入工程失败解决方法
- 第一篇博客
- 关于安装Zookeeper 服务端问题解决
- 自定义UIbutton的样式
- 红黑树的C++实现(2)
- thinkphp中url的生成U()方法
- Android中的MVP架构
- linux shell “(())” 双括号运算符使用
- js获取子元素
- mysql的一些问题
- 安卓中轻量级数据库SQLite的使用
- spring hadoop 系列(二)
- word如何关联博客
- javaWeb 复习系列(二)