单例模式
来源:互联网 发布:国产数据库有哪些 编辑:程序博客网 时间:2024/06/05 16:25
单例模式,是一种常用的软件设计模式,在它的核心结构中只包含一个被称为单例的特殊类,通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。
第一种:饿汉式
public class SingleEasy { private SingleEasy(){ } //类初始化的时候就已经加载 private static SingleEasy singleEasy=new SingleEasy(); public static SingleEasy getInstance(){ return singleEasy; }}
饿汉式的话不存在多线程同步加载的问题,类初始化时就已经加载,做不到使用的时候才加载。
第二种:懒汉式(线程不安全)
public class SingleNotEmptyEasy { private static SingleNotEmptyEasy singleNotEmptyEasy; private SingleNotEmptyEasy(){ } public static SingleNotEmptyEasy getInstance(){ //对象为空才去实例化 if(singleNotEmptyEasy==null){ singleNotEmptyEasy=new SingleNotEmptyEasy(); } return singleNotEmptyEasy; }}
懒汉式是在使用的时候才会去加载,不过当多次同时去加载的时候就会存在线程安全问题。
第三种:懒汉式(线程安全)
public class SingleNotEmptyEasy { private static SingleNotEmptyEasy singleNotEmptyEasy; private SingleNotEmptyEasy(){ } public static synchronized SingleNotEmptyEasy getInstance(){ //对象对空才去实例化 if(singleNotEmptyEasy==null){ singleNotEmptyEasy=new SingleNotEmptyEasy(); } return singleNotEmptyEasy; }}
就是在第二种的getInstance方法上面加了一个同步锁synchronized,每次在使用加载的时候都会先去校验,如果已经有在加载了,就不会去加载,而是要等前面的加载完了,才会去加载,这样线程安全,但是每次都去校验synchronized会造成效率的下降。
第四种:DCL
public class DCLSingle { private volatile static DCLSingle dclSingle; private DCLSingle(){ } public static DCLSingle getInstance(){ if(dclSingle==null){ synchronized (DCLSingle.class){ if(dclSingle==null){ dclSingle=new DCLSingle(); } } } return dclSingle; }}
DCL模式的不同是没有将同步锁加载方法上,而是加在代码块里面,如果单例对象不为空就直接返回,如果为空就会走到加了同步锁的代码块中,还会进行第二次校验,这样子提高了效率,同时也保证了线程的安全,这种模式还涉及到一个java的关键字volatile,加了volatile,可以保证无论何时读取这个变量,都是读到内存中最新的值,无论何时写这个变量,都可以立即写到内存中。
第五种:内部类模式
public class InnnerClassSingle { private InnnerClassSingle(){ } private static class SingleHolder{ private static InnnerClassSingle innnerClassSingle=new InnnerClassSingle(); } public static InnnerClassSingle getInstance(){ return SingleHolder.innnerClassSingle; }}
内部类模式是一种比较优雅的饿汉式,它是在InnnerClassSingle内中再建一个SingleHolder内部类,在内部类中创建一个InnnerClassSingle对象,通过内部类调用加载实例化,这样子不会随着类的加载的而实例化,做到了使用的时候才实例化。
第六种:枚举模式
public enum EnumManager { SDCardManager(10){ @Override public EnumManager getSingle() { return SDCardManager; } } , HttpManager(1){ @Override public EnumManager getSingle() { return HttpManager; } }; public abstract EnumManager getSingle(); private EnumManager(int type){ }}
这里需要注意的是枚举的构造方法是私有的,变量的声明要在构造方法之前。
- 单例、单例模式
- 单例模式-多线程单例模式
- 单件模式(单例模式)
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- PHP模式-单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- 设计模式--单例模式
- 设计模式-单例模式
- 单例模式(单子模式)
- 设计模式-单例模式
- [设计模式] 单例模式
- Spark踩坑
- linux下Nginx配置文件(nginx.conf)配置设置详解(windows用phpstudy集成)
- 配置文件
- 频道管理集成
- 第三方依赖
- 单例模式
- 频道管理,城市列表 配置
- Eclipse Maven Tomcat,'搭建与部署'一站解决(多图)
- ora-01652无法通过128(在表空间temp中)扩展temp段
- Windows下用Composer安装Laravel步骤(集成php环境用phpStudy2016版本)
- 机器学习(绘图)
- 试试看
- URI和URL的区别
- 常用配置