单例模式
来源:互联网 发布:投诉淘宝小二判决电话 编辑:程序博客网 时间:2024/05/18 03:08
华为面试题(单例模式):
java模式之单例模式:
单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。
特点:
1,一个类只能有一个实例
2,自己创建这个实例
3,整个系统都要使用这个实例
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。一些资源管理器常常设计成单例模式。
外部资源:譬如每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口被两个请求同时调用。内部资源,譬如,大多数的软件都有一个(甚至多个)属性文件存放系统配置。这样的系统应当由一个对象来管理这些属性文件。
还有, singleton能够被状态化; 这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口的情况下方便的做到。
另外方面,Singleton也能够被无状态化。提供工具性质的功能,
Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection)。
我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。
一个例子:Windows 回收站。
在整个视窗系统中,回收站只能有一个实例,整个系统都使用这个惟一的实例,而且回收站自行提供自己的实例。因此,回收站是单例模式的应用。
两种形式:
1,饿汉式单例类
public class Singleton { private Singleton(){} //在自己内部定义自己一个实例,是不是很奇怪? //注意这是private 只供内部调用 private static Singleton instance = new Singleton(); //这里提供了一个供外部访问本class的静态方法,可以直接访问 public static Singleton getInstance() { return instance; } }
2,懒汉式单例类
public class Singleton { private static Singleton instance = null; public static synchronized Singleton getInstance() { //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次 //使用时生成实例,提高了效率! if (instance==null) instance=new Singleton(); return instance; } }
(第一种加载类时,instance马上就被实例化,第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了,instance并没有马上被实例化,只有调用方法getInstance()的才被实例化)
看下一个例子就知道了。
jex1:public class Singleton { private static final Singleton singleton = null; private Singleton() { } public static Singleton getInstance() { if (singleton== null) { singleton= new Singleton(); } return singleton; } }这个不多说了,肯定是错误的,如果多个线程访问的时候都==null,那么接下来就是产生多个实例。不算单例模式。
ex2:public class Singleton { private static final Singleton singleton = null; private Singleton() { } public static Singleton getInstance() { if (singleton== null) { synchronized (Singleton.class) { singleton= new Singleton(); } } return singleton; } }这个虽然加了同步锁,但是如果多个线程同步访问==null,那么还是会产生多个实例,只是产生实例的时候同步而已。
ex3: public class Singleton { private static final Singleton singleton = null; private Singleton() { } public static Singleton getInstance() { synchronized (Singleton.class) { if (singleton== null) { singleton= new Singleton(); } } return singleton; } }这个就可以了,但是这个地方对于每个访问的这个方法都是同步,而最需要的同步只是在new的地方,所以这样做虽然保证了单例,但是效率有点低哦。
ex4:public class Singleton { private static final Singleton singleton = null; private Singleton() { } public static Singleton getInstance() { if (singleton== null) { synchronized (Singleton.class) { if (singleton== null) { singleton= new Singleton(); } } } return singleton; } }这个不错,保证了单例。这个叫做double-check 双重检查。
还有一个比较简单的写法。
ex5:public class Singleton { private static final Singleton singleton = new Singleton(); private Singleton() { } public static Singleton getInstance() { return singleton; } }这个看起来要简单好多。
第三种:
如读 property 属性文件,内存只要一份就可以了。设计为单例模式。在静态代码块。
class PropertiesMgr{private static Properties props=new Properties();static{try {props.load(Test.class.getResourceAsStream("*.propeties"));} catch (IOException e) {e.printStackTrace();}}public String getProperty(String key){return props.getProperty(key);}}全程就读一次硬盘。
这个有缺陷:改了不能马上起作用,内存缓存没变。 解决办法,文件改了把文件重新load 一遍。
- 单例、单例模式
- 单例模式-多线程单例模式
- 单件模式(单例模式)
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- PHP模式-单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- 设计模式--单例模式
- 设计模式-单例模式
- 单例模式(单子模式)
- 设计模式-单例模式
- [设计模式] 单例模式
- POJ3281 Dining [最大流应用]
- 启用长按事件 UILongPressGestureRecognizer
- 029
- hdu 1013 Digital Roots
- 项目现场开发感想
- 单例模式
- C#实现图片的放大缩小、左旋右旋,PS无法保存变化后的图片求辅导
- JS的IE和Firefox兼容性汇编<转>
- Dalvik——如何控制vm
- Mysql 备份与恢复
- Hadoop的环境搭建,和编写一个简单的hadoop job
- HDU/HDOJ 1396 浙大月赛2003年
- Classworking 工具箱: 注释(Annotation)与 ASM 自动化运行时类文件修改
- hdu 1056 HangOver(水)