单例设计模式入门
Posted overmatch
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例设计模式入门相关的知识,希望对你有一定的参考价值。
单例模式:它是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类;通过单例模式可以保证系统中,应用该模式的一个类只有一个实例。即一个类只有一个对象实例。
在java语言中,单例带来了两大好处:
1.对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级的对象而言,是非常可观的一笔系统开销。
2.由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间。
所以对于系统的关键组件和被频繁操作的对象,使用单例模式便可以有效地改善系统性能。
单例类必须要有一个private访问级别的构造函数,只有这样,才能确保单例不会在系统中的其他代码内被实例化,这点是相当重要的;其次,instance成员和getInstance()方法必须是static的。
单例代码:饿汉式,懒汉式示例
1 package com.itycl; 2 3 public class SingleDemo { 4 //private static final SingleDemo s = new SingleDemo();//饿汉式 5 private static SingleDemo s =null; 6 private SingleDemo() { 7 System.out.println("create singleDemo!"); 8 } 9 10 public static SingleDemo getInstance() { 11 if(s==null) { 12 s=new SingleDemo(); 13 } 14 return s; 15 16 } 17 public static void createString() { 18 System.out.println("createString!"); 19 } 20 }
饿汉式:这种单例的实现方式非常简单,而且十分可靠,它唯一的不足仅是无法对instance实例做延迟加载,假如单例的创建过程很慢,而由于instance成员变量是static定义的,因此在JVM加载单例类时,单例对象就会被建立,如果此时,这个单例类在系统中还扮演其他角色,那么在任何使用这个单例类的地方都会初始化这个单例变量,根本就不会管是否被用到。
懒汉式:在饿汉式基础下,这次改良主要是从JVM加载类的原理上进行改良的,上面的代码在初始化类的时候给instance赋予null,确保系统启动的时候没有额外的负载,其次,在getInstance方法中加入判断单例是否存在,不存在才new。但是getInstance()方法必须是同步的,否则多线程环境下,可能线程1正在创建单例时,线程2判断单例instance为空,就会创建多个实例。
最完整的单例写法,内部类实现:
1 package com.itycl; 2 3 public class FinalSingleDemo { 4 private FinalSingleDemo() {//私有化构造器 5 System.out.println("create finalsingleDemo"); 6 } 7 8 public static class singleFolder { 9 private static final FinalSingleDemo sf = new FinalSingleDemo(); 10 11 } 12 13 public static synchronized FinalSingleDemo getInstance() { 14 return singleFolder.sf; 15 16 } 17 18 }
在这个实现中,用内部类来保护单例,当FinalSingleDemo类被加载时,内部类不会被初始化,所以可以确保FinalSingleDemo类被载入JVM时,不会初始化单例类,当getInstance方法被调用时,才会加载singleFolder,从而初始化instance,同时,由于实例的建立是在类加载时完成的,故天生对多线程友好,getInstance()方法也不需要使用synchronized修饰,因此,这种实现能兼顾前两种写法的优点(延迟加载,非同步)。
以上是关于单例设计模式入门的主要内容,如果未能解决你的问题,请参考以下文章
《C#零基础入门之百识百例》(四十五)类的属性 -- 单例模式