单例设计模式

一、什么是单例设计模式

单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。
许多时候整个系统只需要拥有一个全局的对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。

二、单例实现的两个步骤

1.将该方法的构造方法定义为私有方法,这样其他的代码就无法通过该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例
2.在该类内提供一个静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并返回。

三、单例模式的优缺点

优点:

  • 在内存中只有一个对象,节省内存空间
  • 避免频繁的创建销毁对象,可以提高性能
  • 避免对共享资源的多重占用,简化访问
  • 为整个系统提供一个全局访问点

缺点:

  • 不适用于变化频繁的对象
  • 如果实例化的对象长时间不被引用,系统会认为该对象是垃圾而被回收,这可能会导致对象状态的丢失。

四、单例的实现

1.饿汉式

	public class Singleton1{
			private static Singleton1 singleton1 = new Singleton1();
			private Singleton1(){}
			private static Singleton1 getSingleton1(){
			return singleton1;
			}
			}

类加载是加载一次,只要这个类的字节码文件被类加载器加载到内存当中,就会开始执行初始化,这个时候就会加载静态资源,比如静态代码块和静态初始化(这里是静态初始化)。加载就会生成一个对象,由于只加载一次,就只会生成一个对象。
优点:写法简单,避免了线程同步问题。
缺点:在类的加载的时候就完成了实例化,没有达到懒加载的效果,如果一直没用过这个实例,则会造成内存的浪费。
2.懒汉式

public class Singleton2{
			private static Singleton2 singleton2;
			private Singleton2(){};
			public static Singleton2 getSingleton2(){
			if(singleton2 == null){
				singleton2 = new Singleton2();
				}
			return singleton2;
		}
		}

从懒汉式单例可以看出,单例实例被延迟加载,只有在真正用到的时候才会实例化一个对象并交给自己的引用。
但缺点也很明显,只能在单线程下引用。如果在多线程下,两个线程进入了判断的语句块(此时两个线程共享的singleton2实例都是null),一个线程生成了一个对象,另一个也生成了对象(试问:这两个对象是一样的吗?满足单例设计模式了吗?)这时有人会想了,加个锁,好,那就来加锁

public class Singleton3{
			private static Singleton3 singleton3;
			private Singleton3(){};
			public synchronized static Singleton3 getSingleton3(){
			if(singleton3 == null){
				singleton3 = new Singleton3();
				}
			return singleton3;
		}
		}

线程安全了,一次只能生成一个对象,但线程锁降低了效率(多个线程都在等),这时候还有几种类似的方式,但都不是最好的,接下来介绍最好的方式,也是需要记的,双重加锁机制

public class Singleton4{
			private static Singleton4 singleton4;
			private Singleton4(){};
			public static Singleton4 getSingleton4(){
			if(singleton4 == null){
				synchronized (Singleton4.class){
				if(singleton4 == null)
				singleton4 = new Singleton4();
				}
			}
			return singleton4;
		}
		}

有什么区别呢?各位发现了吗?一方面生成对象的时候只能有一个线程进入,并且判断语句决定了只会生成一个对象,同时,之后再有多个线程进入的时候,不需要加锁了,因为第一个判断语句都过不去,压根不进去执行。
以上代码内容纯手打,如遇运行报错,自行调式。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值