设计模式之单例模式
来源:互联网 发布:电脑怎么连接多重网络 编辑:程序博客网 时间:2024/05/07 05:40
什么是单例模式
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。
简单点说,就是只要一个就够了,多了就就浪费资源。比如一个宿舍有四个人,只有一个拖把,谁需要谁用即可,没必要每人都有一个。
我们在操作数据库的时候经常使用,service和dao,通常我们每次用户访问一次都要创建一个新的对象,用完销毁。而使用单例模式可以让一个对象为所有用户服务。
单例模式的特点
2.单例类必须自己创建自己的唯一实例。
3.单例类必须给所有其他对象提供这一实例。
单例模式的作用
保证在Java应用程序中,一个类Class只有一个实例存在。
懒汉式(使用时才创建对象,不使用不创建)
1.普通单例
public class Singleton {private static Singleton single = null;private Singleton() {}public static Singleton getSingleton() {//如果当前的single对象为null 创建对象if (single == null) {single = new Singleton();}return single;}}
private修饰的single和构造方法(如果构造方法为public修饰 就不是单例模式了)。public修饰的getSingleton方法返回该类中的唯一实例。
ps:即使为私有的构造方法 也可以通过java反射机制来为其实例化 这里不考虑。
那么懒汉式方法真的好吗?仔细分析,如果在single未实例化之前,有两个线程同时访问该getSingleton方法会怎样呢(并发)?这样系统就会调用两次构造方法,
也就实例化了两次single对象。如果这样写单例模式 只会让别人认为我们仅仅是了解了单例模式,并没有深入思考。
这时候肯定该说了 我大JAVA语言有synchronized关键字,分分钟让你只有一个线程访问。
2.synchronized
public class Singleton {private static Singleton single = null;private Singleton() {}public static synchronized Singleton getSingleton() {//如果当前的single对象为null 创建对象if (single == null) {single = new Singleton();}return single;}}分析:
使用synchronized的确很好的解决了线程并发的问题。但是有没有想过在每次使用synchronized也会浪费时间的。
虽然计算机的执行速度很快,但是久而久之 浪费的世间就很多了。我们只想加一次synchronized锁怎么办呢?
需要使用另外一个关键字volatile。
(小知识点:
volatile的作用是: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.
比如
a=5;a=6;a=7;编译器会对这三条语句优化 只执行最后一条语句,也只产生一条机器码。最后a=7.而使用volatile关键字,
则编译器会逐一的进行编译并产生相应的机器代码(产生三条代码).
)
3.synchronized+双重检验
public class Singleton {//使用volatile关键字修饰private static volatile Singleton single = null;private Singleton() {}//双重检验的方法public static synchronized Singleton getSingleton() {//如果当前的single对象为null 创建对象if (single == null) {synchronized (Singleton.class) {if(single==null){single = new Singleton();}}}return single;}}分析:
比上个代码更加节省时间。
并发情况运行分析:
1.线程1进入getSingleton方法。
2.由于single=null,线程1进入synchronized块,线程2执行。
3.线程2进入getSingleton方法
4.single=null,线程2试图进入synchronized块,当此时线程1在synchronized块,线程2进入阻塞,线程1执行
5.线程1:在synchronized块的if语句中由于single仍然等于null, 为single实例化。
6.线程1退出synchronized块并返回single实例,线程2执行
7.线程2进入synchronized块,并判断当前single是否等于null,
8.线程2:由于当前single不为null,退出synchronized块,由线程1创建的single实例返回为线程2
饿汉式(即使没有线程访问也会创建对象)
public class Singleton {// 直接创建一个实例 并且只会创建一次private static final Singleton single = new Singleton();private Singleton() {}public static Singleton getSingleton() {// 返回已经创建好的实例return single;}}
分析:
定义了一个静态变量single ,并且只创建一次实例,线程安全,以后不再改变。缺点就是一开始就申请号 浪费了一点资源。
静态内部类
public class Singleton {private static class SingletonHolder {// 静态初始化 JVM保证线程安全private static final Singleton single = new Singleton();}private Singleton() {}public static Singleton getSingleton() {return SingletonHolder.single;}}分析:
SingletonHolder类级内部类,和外部类没有联系。只有使用的时候才会被加载。线程安全。上上之选的方法、
虽然静态内部类已经很好了 但是人们总是有追求的 在Java1.5发行版之后,使用枚举能够实现单例
枚举实现单例也就成了最优秀的方法,因为它线程安全,简单,并且枚举也提供了序列化机制。
下面通过一个例子来了解把
枚举单例
class Singleton{private String message;public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}}public enum EnumSingleton {//枚举属性 一般大写 SINGLETON; private Singleton single; //私有的构造方法 private EnumSingleton(){ single=new Singleton(); } //获取器 public Singleton getSingleton(){ return single; } //使用方法 public static void main(String[] args) { Singleton single=EnumSingleton.SINGLETON.getSingleton(); single.setMessage("枚举实现单例模式"); System.out.println(single.getMessage()); }}运行结果:枚举实现单例模式
使用枚举单例能够提高别人对你水平的看法哦~
- 设计模式之 单例设计模式
- 设计模式之 单例设计模式
- 设计模式之单例设计模式
- 设计模式之-----------单例设计模式
- 设计模式之:单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之-单例设计模式
- 设计模式之单例设计模式 标签: 设计模式
- 设计模式之单例
- 设计模式之单例
- 设计模式之 单例
- .NET MVC和JAVA MVC有什么区别?
- JAVA学习记录——文件读取
- LightOJ-1063-tarjan
- 2016.11.8打卡 距NOIP11天
- 最简单的jdbc连接查询
- 设计模式之单例模式
- “==”和equals的区别笔记
- 设计模式之单例模式 (五种单例模式实现方式) 并利用CountDownLatch类在多线程下比较效率
- 随便的感想
- 【封装】ReadFromFile——从文件中读取数据
- gets 与 scanf 的区别
- C++类const成员函数
- 将csv文件导入oracle中
- JS版设计模式--Factory