java设计模式-单例模式

保证一个类只有一个实例,并提供一个唯一的全局访问点。

1、介绍

单例模式的功能

       保证这个类在运行期间只会被创建一个类实例,并提供一个全局唯一访问这个类实例的访问点。

单例模式的范围

       是一个ClassLoader及其子ClassLoader的范围。

单例模式的命名

       一般建议单例模式的方法命名为:getInstance()。

单例模式的本质

       控制实例数目

何时选用单例模式

       当需要控制一个类的实例只能有一个,而且客户只能从一个全局访问点访问它时,可以选择单例模式。

单例模式使用场景

  1. 配置文件的读取,由于配置文件是共享资源。
  2. 应用程序的日志记录,日志属于共享文件,只能有一个实例去操作。
  3. 数据库连接池,多线程线程池。
  4. 网站计数器,否则难以同步。

2、结构说明

Singleton:

       负责创建Singleton类自己的唯一实例,并提供一个getInstance的方法,让外部来访问这个类的唯一实例。

3、单例模式实现方式

懒汉式、饿汉式、双重检查加锁、枚举类实现

单例模式调用顺序示意图

一种更好的单例实现方式

Lazy initialization holder class模式,这个模式综合使用了Java的类级内部

类和多线程缺省同步锁的知识,很巧妙的同时实现了延迟加载和线程安全。

单例和枚举

Singleton的最佳方法。

(1)Java的枚举类型实质上是功能齐全的类,因此可以有自己的属性和方法

(2)Java枚举类型的基本思想:通过公有的静态final域为每个枚举常量导出实

例的类

(3)从某个角度讲,枚举是单例的泛型化,本质上是单元素的枚举

用枚举来实现单例非常简单,只需要编写一个包含单个元素的枚举类型即可

4、单例模式中的编程思想

延迟加载思想

       一开始不加载资源或数据,一直等到马上要使用这个资源或数据了才去加载,也称Lazy Load,尽可能节约资源。

缓存思想

       某些资源或数据会被频繁使用,可以将这些数据缓存到内存中,每次操作时,先到内存里面找,如果有就直接使用,如果没有就获取它,并设置到缓存中,下一次访问的时候就可以直接从内存中获取了。从而节省大量的时间,缓存是一种典型的空间换时间的方案。

5、单例模式优缺点

  1. 时间和空间:懒汉式典型的时间换空间,饿汉式空间换时间。
  2. 线程安全:

不加同步的懒汉式是线程不安全的

       饿汉式是线程安全的,因为虚拟机保证了只会装载一次。

       如何实现懒汉式线程安全,加上synchronized即可。

       双重检查锁

       所谓双重检查加锁机制,指的是:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法过后,先检查实例是否存在,如果不存在才进入下面的同步块,这是第一重检查。进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。这样一来,就只需要同步一次了,从而减少了多次在同步情况下进行判断所浪费的时间。

       双重检查加锁机制的实现会使用一个关键字volatile,它的意思是:被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。

注意:在Java1.4及以前版本中,很多JVM对于volatile关键字的实现有问题,会导致双重检查加锁的失败,因此本机制只能用在Java5及以上的版本。

6、代码示例

/**
 * 使用枚举来实现单例模式的示例
 */
public enum Singleton {	
	/**
	 * 定义一个枚举的元素,它就代表了Singleton的一个实例
	 */
	uniqueInstance;
	
	/**
	 * 示意方法,单例可以有自己的操作
	 */
	public void singletonOperation(){
		//功能处理
		System.out.println("aa=="+Singleton.uniqueInstance.hashCode());
	}
}

/**
 * 单例示例   懒汉式
 */
public class Singleton {
	/**
	 * 定义一个变量来存储创建好的类实例
	 */
	private static Singleton uniqueInstance = null;
	/**
	 * 私有化构造方法,好在内部控制创建实例的数目
	 */
	private Singleton(){
		
	}
	/**
	 * 定义一个方法来为客户端提供类实例
	 * @return 一个Singleton的实例
	 */
	public static synchronized Singleton getInstance(){
		//判断存储实例的变量是否有值
		if(uniqueInstance == null){
			//如果没有,就创建一个类实例,并把值赋值给存储类实例的变量
			uniqueInstance = new Singleton();
		}
		//如果有值,那就直接使用
		return uniqueInstance;
	}
	/**
	 * 示意方法,单例可以有自己的操作
	 */
	public void singletonOperation(){
		//功能处理
	}
	/**
	 * 示意属性,单例可以有自己的属性
	 */
	private String singletonData;
	/**
	 * 示意方法,让外部通过这些方法来访问属性的值
	 * @return 属性的值
	 */
	public String getSingletonData(){
		return singletonData;
	}
}

/**
 * 饿汉式单例实现的示例
 */
public class Singleton {
	/**
	 * 定义一个变量来存储创建好的类实例,直接在这里创建类实例,只会创建一次
	 */
	private static Singleton uniqueInstance = new Singleton();
	/**
	 * 私有化构造方法,好在内部控制创建实例的数目
	 */
	private Singleton(){
		
	}
	/**
	 * 定义一个方法来为客户端提供类实例
	 * @return 一个Singleton的实例
	 */
	public static Singleton getInstance(){
		//直接使用已经创建好的实例
		return uniqueInstance;
	}
	
	/**
	 * 示意方法,单例可以有自己的操作
	 */
	public void singletonOperation(){
		//功能处理
	}
	/**
	 * 示意属性,单例可以有自己的属性
	 */
	private String singletonData;
	/**
	 * 示意方法,让外部通过这些方法来访问属性的值
	 * @return 属性的值
	 */
	public String getSingletonData(){
		return singletonData;
	}
}

/**
 * 使用缓存来模拟实现单例
 */
public class Singleton {
	/**
	 * 定义一个缺省的key值,用来标识在缓存中的存放
	 */
	private final static String DEFAULT_KEY = "One";
	/**
	 * 缓存实例的容器
	 */
	private static Map<String,Singleton> map = new HashMap<String,Singleton>();
	/**
	 * 私有化构造方法
	 */
	private Singleton(){
		//
	}
	public static Singleton getInstance(){
		//先从缓存中获取
		Singleton instance = (Singleton)map.get(DEFAULT_KEY);
		//如果没有,就新建一个,然后设置回缓存中
		if(instance==null){
			instance = new Singleton();
			map.put(DEFAULT_KEY, instance);
		}
		//如果有就直接使用
		return instance;
	}
	
	public static void main(String[] args) {
		
		for(int i=0;i<3;i++){
			System.out.println(Singleton.getInstance());
		}
		
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值