Java 实现单例(Singleton)模式
2015-11-26 09:06
495 查看
单例模式Singleton解释
版本一单线程环境
版本二多线程环境 同步延迟加载
版本三多线程环境进阶1 双重检测同步延迟加载
版本四多线程环境进阶2 非延迟加载单例类
版本五多线程环境进阶3 使用内部类实现延迟加载
只有当上面代码中的 instance静态变量为空的时候,才会去创造一个实例,同时构造函数定义为私有,这样就确保Singleton这个类只创建了一个实例
为了保证在多线程的环境下只能得到类的一个实例,我们在getInstance()方法上加一个同步关键词synchronized ,这样可以保证在多个线程同时访问getInstance()方法时,只有一个线程能否进入函数体,其他线程等待,当第一个线程执行完函数体后,第二线程进入,剩余线程等待…..,这样就保证类只有一个实例
这里的instance 实例在第一次使用Singleton这个类型的时候自动初始化,假设Singleton类中还有其他的静态函数,那么调用该静态函数也会初始化instance 变量,这就导致过早的初始化instance 变量,从而降低了内存的使用效率。
上面代码在Singleton类中定义了一个私有类Holder ,当第一次使用到Holder 类型时,会创建instance ,而Holder 类型只在getInstance()方法中使用到,如果我们不调用getInstance(),就不会触发instance的创建操作,从而做到真正的按需创建。
版本一单线程环境
版本二多线程环境 同步延迟加载
版本三多线程环境进阶1 双重检测同步延迟加载
版本四多线程环境进阶2 非延迟加载单例类
版本五多线程环境进阶3 使用内部类实现延迟加载
单例模式(Singleton)解释
只生成一个实例的的类是实现了单例(Singleton)模式的类型。版本一:单线程环境
public class Singleton{ private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
只有当上面代码中的 instance静态变量为空的时候,才会去创造一个实例,同时构造函数定义为私有,这样就确保Singleton这个类只创建了一个实例
版本二:多线程环境 (同步延迟加载)
版本一可以在单线程中正常运行,但多线程就出现了问题。假想现在有两个线程同时运行判断语句instance == null,并且此时instance还没有创建,那么两个线程都会创建一个实例,此时这个类就不满足单例模式了。当然,如果有同时又更多的线程执行判断语句instance == null,并且此时instance还没有创建,那么会创建更多的实例。为了保证在多线程的环境下只能得到类的一个实例,我们在getInstance()方法上加一个同步关键词synchronized ,这样可以保证在多个线程同时访问getInstance()方法时,只有一个线程能否进入函数体,其他线程等待,当第一个线程执行完函数体后,第二线程进入,剩余线程等待…..,这样就保证类只有一个实例
public class Singleton{ private static Singleton instance = null; private Singleton(){} public static synchronized Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
版本三:多线程环境(进阶1 双重检测同步延迟加载 )
版本二固然可以在多线程环境下正常运行,但是效率不高。考虑如下的情况:当instance 已经被初始化后,有多个线程访问getInstance()方法,但是由于线程同步锁的原因,线程只能一个接一个的执行getInstance()方法,这期间线程的等待就浪费了许多时间。为了解决这个问题就出现了如何下解决方案,现在只有当instance为null的时候才会加锁操作,否则无需加锁操作。public class Singleton{ private static Singleton instance = null; private Singleton(){} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { instance = new Singleton(); } } return instance; } }
版本四:多线程环境(进阶2 非延迟加载单例类 )
为了让代码更加优雅,简洁,同时健壮性很好,就出现了非延迟加载单例类,又被称之为饿汉式.public class Singleton{ private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance() { return instance; } }
这里的instance 实例在第一次使用Singleton这个类型的时候自动初始化,假设Singleton类中还有其他的静态函数,那么调用该静态函数也会初始化instance 变量,这就导致过早的初始化instance 变量,从而降低了内存的使用效率。
版本五:多线程环境(进阶3 使用内部类实现延迟加载 )
public class Singleton{ private Singleton(){} public static Singleton getInstance() { return Holder.instance; } private static class Holder { static Singleton instance = new Singleton(); } }
上面代码在Singleton类中定义了一个私有类Holder ,当第一次使用到Holder 类型时,会创建instance ,而Holder 类型只在getInstance()方法中使用到,如果我们不调用getInstance(),就不会触发instance的创建操作,从而做到真正的按需创建。
相关文章推荐
- 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简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树