分析设计单例模式的几种方法以及单例模式的优点

1.为什么要用单例模式?

 (1)对于频繁使用的对象,可以省略对象创建时所消耗的时间。尤其是对重量级系统而言是一个非常可观的系统开销。

 (2)由于new对象的次数变小,系统的内粗消耗也会降低,可以减轻gc的压力,缩短gc停顿时间。

2.设计单例模式的几种方法

(1)简单的单例模式

public class Singleton {
	private Singleton() {
		System.out.println("Singleton is  created");
	}
	private static Singleton instance = new Singleton();
	public static Singleton getInstance() {
		return instance;
	}
}

这种设计单例模式的方法虽然简单,但是无法对instance对象做延迟加载,因为instance是static修饰的,所以当jvm加载类的时候就会常见instance对象,如果此时单例类中还有其他方法,在任何使用该单例类的时候就是加载instance对象,而不管instance方法是否被用到。

(2)懒加载及实现线程安全的单例模式

/**
 * @author 江鹏飞
 * 单例对象的延迟加载及线程安全实现
 */
public class LazySingleton {
	private LazySingleton(){
		System.out.println("lazySingleton is created!");
	}
	private static LazySingleton singleton = null;
	public static synchronized LazySingleton getLazySingleton(){
		if(singleton==null){
			singleton = new LazySingleton();
		}
		return singleton;
	}
}

这种方法解决了(1)中的延迟加载问题以及保证了线程安全(因为在不同线程调用getLazySingleton()时在一个线程创建对象前,另外一个线程调用的时候会误认为当前instance为空),这种方法虽然解决了上述问题,但是如果在代码中使用synchronized时在多线程环境会出现线程阻塞影响系统效率。显然这个也不是一个很好的实际方法。

(3)使用内部类的方式设计单例模式(推荐)

/**
 * @author 江鹏飞
 *	使用内部类的方式实现单例模式
 */
public class StaticSingleton {
	private StaticSingleton(){
		System.out.println("StaticSingleton is created!");	
	}
	private static class SingletonHolder{
		private static StaticSingleton instance = new StaticSingleton(); 
	}
	public static StaticSingleton getInstance(){
		return SingletonHolder.instance;
	}
}

这种方法解决了(2)中多线程环境下线程阻塞问题提高了系统的性能,使用内部类来维护单例的实例,当StaticSingleton 被加载时它的内部类并不会初始化。当StaticSingleton 被jvm加载时单例类SingletonHolder不会被初始化,而当调用 getInstance()方法时内部类才会被jvm加载从而初始化instance,因为实例对象的创建在类加载时完成,则天生对线程友好。getInstance()也不需要synchronize修饰。这实现方式同时具备以上两种实现的优点。

注意: 通常情况下用上面设计的单例方法可以确保系统中只存在一个实例,但是当通过反射机制,强行调用单例类的私有构造函数生成多个单例。

(4)序列化/反序列化的单例实现

package com.ycit.singleton;

import java.io.Serializable;

/**
 * @author 江鹏飞
 *	序列化反序列化单例模式的实现
 */
public class SerSingleton implements Serializable {
	String name;
	private SerSingleton() {
		System.out.println("Singleton is  created");
		name="SerSingleton";
	}
	private static SerSingleton instance = new SerSingleton();
	public static SerSingleton getInstance() {
		return instance;
	}
	private Object readResolve(){
		return instance;
	}
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值