设计模式:创建型模式-----单例模式

相关知识点:
1.概述
单例模式是java中最简单的设计模式之一,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类。

2.使用单例模式的三个关键步骤
a.将构造方法私有化—防止外界创建对象
b.创建自己的对象
c.给外界访问方式

3.优缺点
优点:
提供了对唯一实例的受控访问。
由于在系统内存中只存在一个对象,因此可以节约系统资源。
允许可变数目的实例。

缺点:
单例类的扩展有很大的困难。
单例类的职责过重。

4.饿汉模式
这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁synchronized,所以严格意义上并不算单例模式。但是这种方式lazy loading很明显,不要线程安全,在多线程不能正常工作。
缺点:浪费空间,且不支持多线程。
5.懒汉模式
优点:第一次调用才初始化,避免浪费空间
缺点:必须加锁synchronized才能保证单例,但加锁会影响效率。
getInstance()的性能对应用程序不是很关键(该方法使用不太频繁)

a.普通的懒汉模式
这种方式具备很好的layz loading,能够在多线程中很好的工作,但是效率很低,99%情况下不需要同步。

b.支持线程安全的懒汉模式
可以有效的解决线程的安全问题

c.支持双重锁的懒汉模式
采用双锁机制,安全且高效

d.静态内部类的懒汉模式
这种方式可以达到与双锁方式一样的功效,但实现更加简单。这种方式只适用于静态域的情况,双锁方式可在实例域需要延迟初始化时使用。

6.应用实例
i.引入单例模式的案例
Person01.java

package demo_singleton01;

public class Person01 {
	//无参构造方法
	Person01(){
		
	}
}

Test01.java

package demo_singleton01;

public class Test01 {
	public static void main(String[] args) {
		Person01 p1=new Person01();
		Person01 p2=new Person01();
		
		//判断这两个对象的内存地址是否相同
		System.out.println(p1==p2);
		System.out.println(p1);
		System.out.println(p2);
		
		//运行后可以发现,在一个项目中,某一指定的类型对象唯一
	}
}

运行结果图
在这里插入图片描述

ii.单例模式的应用案例-----饿汉模式
Person02.java

package demo_singleton02;

//饿汉模式
public class Person02 {
	//1.将构造方法私有化---防止外界创建对象
	private Person02() {
		
	}
	//2.创建自己的对象
	//每次调用都要初始化,非常浪费空间
	private static Person02 p=new Person02();
	//3.给外界访问方式
	public static Person02 getInatance() {
		return p;	
	}
}

Test02.java

package demo_singleton02;

public class Test02 {
	public static void main(String[] args) {
		//Person02 p1=new Person02();
		Person02 p1=Person02.getInatance();
		//Person02 p2=new Person02();
		Person02 p2=Person02.getInatance();
		
		//判断这两个对象的内存地址是否相同
		System.out.println(p1==p2);
		System.out.println(p1);
		System.out.println(p2);
		
		//运行后可以发现,两次创建的对象其对象内存地址相同。
	}
}

运行结果图
在这里插入图片描述

iii.单例模式的应用案例-----普通的懒汉模式
Person03.java

package demo_singleton03;

//懒汉模式
public class Person03 {
	//1.将构造方法私有化---防止外界创建对象
	private Person03(){
		
	}
	//2.创建自己的对象
	private static Person03 p;
	/*3.给外界访问方式
	*a.创建对象
	*b.若之前已被创建,则直接使用之前的对象
	*/
	public static Person03 getInstance() {
		//第一次创建时
		if(p==null) {
			p=new Person03();
		}
		//若之前已被创建,则直接使用之前的对象
		return p;
		
	}
}

Test03.java

package demo_singleton03;

public class Test03 {
	public static void main(String[] args) {
		Person03 p1=Person03.getInstance();
		Person03 p2=Person03.getInstance();
		
		//判断创建出来的两个对象的内存地址是否相同
		System.out.println(p1==p2);
		System.out.println(p1);
		System.out.println(p2);
		
		//运行后可以发现其内存地址相同
	}
}

运行结果图
在这里插入图片描述
iv.单例模式的应用案例-----支持线程安全的懒汉模式
Person04.java

package demo_singleton04;

//懒汉模式(线程安全)
public class Person04 {
	//1.将构造方法私有化---防止外界创建对象
	private Person04(){
		
	}
	//2.创建自己的对象
	private static Person04 p;
	//3.给外界访问方式
	//方法添加线程锁synchronized保证线程安全
	public static synchronized Person04 getInstance() {
		//第一次创建时
		if(p==null) {
			p=new Person04();
		}
		//若之前已被创建,则直接使用之前的对象
		return p;
		
	}
}

Test04.java

package demo_singleton04;

public class Test04 {
	public static void main(String[] args) {
		Person04 p1=Person04.getInstance();
		Person04 p2=Person04.getInstance();
		
		//判断创建出来的两个对象的内存地址是否相同
		System.out.println(p1==p2);
		System.out.println(p1);
		System.out.println(p2);
		
		//运行后可以发现其内存地址相同
	}
}

运行结果图
在这里插入图片描述

v.单例模式的应用案例-----支持双重锁的懒汉模式
Person05.java

package demo_singleton05;

//懒汉模式(双重锁)
//目的:在保证线程安全的情况下尽可能的提高效率
public class Person05 {
	//1.将构造方法私有化---防止外界创建对象
	private Person05(){
		
	}
	
	//2.创建自己的对象
	private static Person05 p;
	
	//3.给外界访问方式
	public static  Person05 getInstance() {
		//第一次创建时
		if(p==null) {
			synchronized(Person05.class) {
				if(p==null) {
					p=new Person05();
				}
			}	
		}
		//若之前已被创建,则直接使用之前的对象
		return p;
		
	}
}

Test05.java

package demo_singleton05;

public class Test05 {
	public static void main(String[] args) {
		Person05 p1=Person05.getInstance();
		Person05 p2=Person05.getInstance();
		
		//判断创建出来的两个对象的内存地址是否相同
		System.out.println(p1==p2);
		System.out.println(p1);
		System.out.println(p2);
		
		//运行后可以发现其内存地址相同
	}
}

运行结果图
在这里插入图片描述

vi.单例模式的应用案例-----支持静态内部类的懒汉模式
Person06.java

package demo_singleton06;

//懒汉模式(静态内部类)
public class Person06 {
	//1.将构造方法私有化---防止外界创建对象
	private Person06(){
		
	}
	
	//2.创建自己的对象(内部类)
	private static class SingletonPerson{
		private static final Person06 p=new Person06();
	};
	
	//3.给外界访问方式
	public static  Person06 getInstance() {
		return SingletonPerson.p;
	}
}

Test06.java

package demo_singleton06;

public class Test06 {
	public static void main(String[] args) {
		Person06 p1=Person06.getInstance();
		Person06 p2=Person06.getInstance();
		
		//判断创建出来的两个对象的内存地址是否相同
		System.out.println(p1==p2);
		System.out.println(p1);
		System.out.println(p2);
		
		//运行后可以发现其内存地址相同
	}
}

运行结果图
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值