Java设计模式之单例模式

        今天看了Java程序性能优化,书中对单例模式进行了详细分析,现在做个总结。

1.概念

         单例模式,顾名思义就是说该单例类为某个具体的类只提供一个实例。比如说Singleton是一个单例类,那么其为A类提供的实例与为B类提供的实例就不一样,具体各位可以做下测试。这也是当初我没理解单例模式的地方。


2.单例模式的两大好处

        1)对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销。

        2)由于new操作的此时减少,因而对系统内存的使用频率也会降低,这将减轻gc压力,缩短gc停顿时间。


3.单例模式角色

        

角色作用
单例类提供单例工厂,返回单例
使用者获取并使用单例类


2.单例模式的几种写法

      1)第一种

public class Singleton
{
	private static Singleton instance = new Singleton();
	
	private Singleton()
	{
		System.out.println("Singleton is create");
	}
	
	public static Singleton getInstance()
	{
		return instance;
	}
        
        /**
        public static void createString()
        {
                System.out.println("createString in Singleton");
        }
       */
 }
这是非常简单的单例模式实现,唯一不足的是无法对instance做延迟加载。试想一下,假如单例对象的创建过程很慢,此时我们只需调用单例类中的createString()方法,该方法是static的,所以只需使用[类名.方法名]调用即可,用不到单例类的实例instance,但是当我们调用createString()方法时,instance也被创建里,即JVM加载该单例类时,instance马上就会被初始化,这无形中增加了系统的负担。解决这个问题的方法就是引入延迟加载机制,看单例模式的第二种。


         2)第二种

public class LazySingleton
{
	private LazySingleton()
	{
		System.out.println("LazySingleton is create");
	}
	
	private static LazySingleton instance = null;
	
	public static synchronized LazySingleton getInstance()
	{
		if(null == instance)
		{
			instance = new LazySingleton();
		}
		
		return instance;
	}
}
这种方式首先将静态成员变量instance初始值赋予null,确保JVM加载单例类时不会初始化instance;其次,在getInstance()方法中,判断当前instance是否为空,若为空则创建单例,否则返回以存在的单例。这保证了当需要使用instance时才实例化它,这是与第一种的区别----延迟加载。

但是记住getInstance()方法必须是同步的,若不是同步的在多线程情况下很有可能导致多个实例被创建,故该方法必须是同步的。这种方式虽然实现了延迟加载,但是和第一种在多线程的环境中相比,它的耗时要远远大于第一种。解决方法看第三种。


           3)第三种

public class StaticSingleton
{
	private StaticSingleton()
	{
		System.out.println("StaticSingleton is create");
	}
	
	private static class SingletonHolder
	{
		private static StaticSingleton instance = new StaticSingleton();
	}
	
	public static StaticSingleton getInstance()
	{
		return SingletonHolder.instance;
	}
}
在这种方法中,单例模式使用内部类来维护单例的实例,当StaticSingleton被加载时,其内部类不会被初始化,完成延迟加载的功能;而当getInstance()方法被调用时,才会加载SingletonHolder,从而初始化instance。同时,由于实例的建立是在类加载时完成,故天生对多线程友好,getInstance()方法也不需要使用同步关键字。因此,这种实现方式同时兼备以上两种实现的优点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值