设计模式之单例模式
2016-04-27 10:54
357 查看
单例模式是一种比较常用的设计模式,提供了对唯一实例的受控访问,由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。
但是,由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出。
如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。(以上是借鉴大神的话,大神说的话总是不可挑剔,嘿嘿)
之前虽然有用过单例模式,但是都没有深入去了解过,直到在一本讲高并发的书上看到,就对单例模式感兴趣起来,现在就来谈谈单例模式吧!
网上搜了很多单例模式的博客,有着各种各样的说法,而我最常用的单例模式是这种(听说这叫双重检查锁定单例模式,又叫懒汉单例模式。好奇怪的名字!):
这种模式第一次使用才初始化,避免浪费内存,但必须加锁才能完成单例,执行效率低
而在高并发这本书中我了解到懒汉单例模式写法的线程安全与高并发的一些知识:
第一种:线程不安全
第二种:线程安全,但是高并发性能不高
第三种:线程安全,性能高,而且最常见的,和上面说的我比较常用的相似,但比我的那个效率高,因为这个加锁的对象是字节对象,占内存低,执行效率会高一丢丢
第四种:线程安全,性能高,我想这个只有经常用多线程的人才会写这个(反正我很少写,这是第二次!)
既然有懒汉单例模式,会不会还有其他的单例模式呢?答案是肯定的,让我们了解另外一种单例模式–饿汉单例模式:
这种单例模式因为没有加锁,执行效率会高,但是类加载时就初始化,很耗内存。
还有一种单例模式叫登记单例模式
听说这是最好的单例模式,解决了上面单例模式的缺点(不知道是不是,再查查,嘿嘿)
定义静态的Singleton instance对象和getInstance()方法
但是,由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出。
如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。(以上是借鉴大神的话,大神说的话总是不可挑剔,嘿嘿)
之前虽然有用过单例模式,但是都没有深入去了解过,直到在一本讲高并发的书上看到,就对单例模式感兴趣起来,现在就来谈谈单例模式吧!
网上搜了很多单例模式的博客,有着各种各样的说法,而我最常用的单例模式是这种(听说这叫双重检查锁定单例模式,又叫懒汉单例模式。好奇怪的名字!):
这种模式第一次使用才初始化,避免浪费内存,但必须加锁才能完成单例,执行效率低
class Person { private static Person instance; private Person(){} public static Person getInstance(){ if(instance == null){ synchronized (Person.class){ if(instance == null){ instance = new Person(); } } } return instance; } }
而在高并发这本书中我了解到懒汉单例模式写法的线程安全与高并发的一些知识:
第一种:线程不安全
class Person { private static Person instance; private Person(){} public static Person getInstance(){ if(instance == null){ instance = new Person(); } return instance; } }
第二种:线程安全,但是高并发性能不高
class Person { private static Person instance; private Person(){} public static synchronized Person getInstance(){ if(instance == null){ instance = new Person(); } return instance; } }
第三种:线程安全,性能高,而且最常见的,和上面说的我比较常用的相似,但比我的那个效率高,因为这个加锁的对象是字节对象,占内存低,执行效率会高一丢丢
class Person { private static Person instance; private static byte[] lock = new byte[0]; private Person(){} public static Person getInstance(){ if(instance == null){ synchronized (lock){ if(instance == null){ instance = new Person(); } } } return instance; } }
第四种:线程安全,性能高,我想这个只有经常用多线程的人才会写这个(反正我很少写,这是第二次!)
class Person { private static Person instance; private static ReentrantLock lock = new ReentrantLock(); private Person(){} public static Person getInstance(){ if(instance == null){ lock.lock(); if(instance == null){ instance = new Person(); } lock.unlock(); } return instance; } }
既然有懒汉单例模式,会不会还有其他的单例模式呢?答案是肯定的,让我们了解另外一种单例模式–饿汉单例模式:
这种单例模式因为没有加锁,执行效率会高,但是类加载时就初始化,很耗内存。
class Person{ private static final Person PERSON = new Person(); private Person(){} public static Person getIntance(){ return PERSON; } }
还有一种单例模式叫登记单例模式
听说这是最好的单例模式,解决了上面单例模式的缺点(不知道是不是,再查查,嘿嘿)
public Person{ private Person(){} private static Person getInstance(){ return Hodler.PERSON; } private static class Hodler{ private static final Person PERSON = new Person(); } }
注意:
单例模式需要私有化构造函数定义静态的Singleton instance对象和getInstance()方法
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用
- 详解C#设计模式编程中生成器模式的使用
- 深入解析C#设计模式编程中对建造者模式的运用