Java设计模式--单例模式【Singleton Pattern】
来源:互联网 发布:大专女生知乎 编辑:程序博客网 时间:2024/06/03 09:19
在宇宙中,太阳是唯一的,独一份的,不可复制的,人们每天抬头看到的太阳都是同一个,不会随着斗转星移就多产生一个太阳,所以太阳就是绝对的单例。下面就以“太阳”为例介绍单例模式。
所谓单例模式就是保证一个类有且只有一个实例。要创建一个独一无二的对象实例,就必须保证程序其他地方不能创建出该单例对象的新实例。设计一个单例类时,需要确定何时初始化该类的单例对象。
1、第一种做法是创建这个类的实例,并将它作为该类的静态成员变量。
package com.pattern.singleton.s2;public class Sunshine { private static Sunshine singleton=new Sunshine(); private Sunshine(){ } public static Sunshine getSunshine(){ return singleton; } }
初试化静态的singleton创建一次。如果我们在Sunshine类里面写一个静态的方法不需要创建实例,它仍然会早早的创建一次实例。而降低内存的使用率。缺点是没有延迟加载lazy loading的效果,从而降低内存的使用率。
2、如果不希望提前创建单例模式,就延迟初始化,在第一次需要它时再创建实例。这就是单例的第二种做法。
package com.pattern.singleton;public class Sunshine { private static Sunshine singleton=null; private Sunshine(){//私有构造方法保证不能让其他地方创造第二个太阳 } public static Sunshine getSunshine(){ if(singleton==null){ singleton=new Sunshine(); } return singleton; } }如果把上述代码放到多线程的环境中,可能会出现两个或多个线程同时初始化一个单例对象的情况。假设第一个线程发现singleton 为null,紧接着第二个线程运行下拉也发现singleton为null,然后两个线程都会对该对象进行实例化。为了避免多个线程同时初始化对象实例,就必须改进上述单例模式设计方法,加入同步机制,实现多线程协调运行。
3、最简单的方式,就是在方法中加入synchronized实现线程同步。
package com.pattern.singleton.s1;public class Sunshine { private static Sunshine singleton=null; private Sunshine(){//私有构造方法保证不能让其他地方创造第二个太阳 } public static synchronized Sunshine getSunshine(){ if(singleton==null){ singleton=new Sunshine(); } return singleton; } }加上了同步锁,使得在多线程的情况下可以用。例如:当两个线程同时想创建实例,由于在一个时刻只有一个线程能得到同步锁,当第一个线程加上锁以后,第二个线程只能等待。第一个线程发现实例没有创建,创建之。第一个线程释放同步锁,第二个线程才可以加上同步锁,执行下面的代码。由于第一个线程已经创建了实例,所以第二个线程不需要创建实例。保证在多线程的环境下也只有一个实例。但是每次通过getSunshine方法得到singleton实例的时候都有一个试图去获取同步锁的过程。加锁是很耗时的,效率太低,所以可以考虑将加锁的过程考虑到方法内。
4、这就出现了双重校验锁的单例模式
package com.pattern.singleton.s1;public class Sunshine { private static Sunshine singleton=null; private Sunshine(){//私有构造方法保证不能让其他地方创造第二个太阳 } public static Sunshine getSunshine(){ if(singleton==null){ synchronized (Sunshine.class) { if(singleton==null){ singleton=new Sunshine(); } } } return singleton; } }只有当singleton为null时,需要获取同步锁,创建一次实例。当实例被创建,则无需试图加锁.缺点是用双重if判断太复杂,容易出错。
那么有没有一种方式,既可以做到延迟加载,又可以避免双重锁的机制呢?
5、匿名内部类-单例模式
package com.pattern.singleton.s1;public class Sunshine { private Sunshine(){//私有构造方法保证不能让其他地方创造第二个太阳 } private static class SunshineFactory{ private final static Sunshine singleton=new Sunshine(); } public static Sunshine getSunshine(){ return SunshineFactory.singleton; } }定义一个私有的内部类,在第一次用这个嵌套类时,会创建一个实例。而类型为SunshineFactory的类,只有在Sunshine.getSunshine()中调用,由于私有的属性,他人无法使用SunshineFactory创建新实例。
源码下载:http://download.csdn.net/download/pelifymeng2/9994100
阅读全文
0 0
- 浅谈 java 设计模式--单例模式(Singleton pattern)
- Java设计模式 - 单例模式(Singleton Pattern)
- JAVA设计模式之 单例模式【Singleton Pattern】
- java设计模式:单例模式【Singleton Pattern】
- Java开发之设计模式--单例模式(Singleton Pattern)
- java设计模式——单例模式(Singleton Pattern)
- java设计模式之单例模式(Singleton pattern)
- Java设计模式之单例模式(Singleton Pattern)
- Java设计模式-单例模式 Singleton Pattern
- Java设计模式之单例模式(Singleton Pattern)
- Java设计模式--单例模式【Singleton Pattern】
- Java设计模式:单例模式(Singleton Pattern)
- Java设计模式之单例模式(Singleton Pattern)
- Java设计模式之单例模式(Singleton Pattern)
- 设计模式 - Singleton Pattern(单例模式)
- 设计模式 - Singleton Pattern(单例模式)
- 设计模式-单例模式(Singleton Pattern)
- 设计模式 -- 单例模式 Singleton Pattern
- Zabbix搭建笔记[2]--Zabbix Agent(Client)的安装配置
- Mybatis通用Mapper
- sync 的使用
- Oil Deposits (DFS)
- 问卷调查Html5开发总结
- Java设计模式--单例模式【Singleton Pattern】
- Collections集合工具类的使用,相关方法.
- 前端特效整理
- android获取so目录的办法
- linux删除指定文件夹中某个文件除外的其他文件
- springboot上传下载
- 学术探讨|人生苦短_你用Python来做啥?
- NIST指纹数据识别
- 单片机外部中断