单例设计模式的详细讲解

单例设计模式

1.什么是单例设计模式?
单例设计模式是设计模式中最常见的一种。设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
在这里插入图片描述
2.在什么时候使用单例设计模式?
(1)在设计一些工具类的时候(通常工具类,只有功能方法,没有属性)
(2)可能会被频繁调用的工具类
3.为什么要使用单例设计模式?
单例设计模式为了避免因为创建了多个实例造成资源的浪费,且多个实例由于多次调用容易导致结果出现错误,而使用单例模式能够保证整个应用中有且只有一个实例。
4.单例设计模式可以解决的问题有哪些呢?
(1)可以保证一个类在内存中的对象的唯一性,在一些常用的工具类、线程池、缓存,数据库,账户登录系统、配置文件等程序中可能只允许我们创建一个对象,这是可以用单例设计模式解决。
(2)创建多个对象可能会引起程序的错误时,可以使用单例设计模式来限制创建对象的个数。
(3)当该对象要被频繁使用时,对内存和效率又有要求时,单例设计模式可以节省重复创建对象带来的内存消耗,从而提高效率。

在对单例设计模式有了一定的了解之后,我们来说说单例设计模式的特点、如何使用单例设计模式和一些注意事项。

5.单例设计模式的特点?
(1)单例类只有一个实例。
(2)单例类必须在其自身进行实例化。
(3)单例类必须向外提供一个获取实例的接口。
6.如何创建单例设计模式?
可分为一下几步:
(1)构造方法私有化,用private使构造方法私有化,使外界无法创建实例。
(2)创建静态的本类对象。
(3)为外界提供获取实例化的接口。

7.接下来我们通过代码来了解一下两种单例设计模式?

饿汉式

class Singleton1{
	//构造方法私有化
	private Singleton1(){}
	//创建静态的本类对象。
	private static Singleton1 s=new Singleton1();
	//为外界提供获取实例化的接口。
	public static Singleton1 getInstance(){
		return s;
	}
	public void print(){
		System.out.println("饿汉式测试");
	}
}	

懒汉式

class Singleton2{
	//构造方法私有化
	private Singleton2(){}
	private static Singleton2 s;
	public static Singleton2 getInstance(){
	//若对象还未创建,创建静态的本类对象。
		if(s==null){
			s=new Singleton2();//懒加载
		}
		//为外界提供获取实例化的接口。
		return s;
	}
	public void print(){
		System.out.println("懒汉式测试");
	}
}

8.以上懒汉法存在线程安全问题。举个例子,在多线程中,有多个线程同时调用getInstance接口来获取实例化,那么可能会出现这种情况。第一个线程判断完if(s==null)还未来得及实例化本类对象。这时第二个线程也进入了判断语句if(s==null),此时s确实为null,所以第二个线程也实例化对象。这样就会实例化两个Singleton对象。

9.那么我们该如何解决这个问题呢?
说白了我们只要实现线程的同步就可以了
线程同步有以下几种方法:
(1)使用同步代码块
(2)使用同步方法
(3)使用Lock(更灵活的代码控制,可以做出判断)

多线程共享数据,会有安全问题,使用同步可以解决安全问题,但同时也牺牲性能,所以同步的代码块要尽量保持简短,把不随数据变化的相关代码移除同步块

那么下面我们用同步方法来举个例子吧

class Singleton2{
	private Singleton2(){}
	private static Singleton2 s;
	//同步方法(synchronized )
	public static synchronized Singleton2 getInstance(){
		if(s==null){
			s=new Singleton2();
		}
		return s;
	}
	public void print(){
		System.out.println("懒汉式测试");
	}
}

但是我们会发现这种方法的同步代码较多,所以较牺牲性能,那有没有其他同步方法能够减少同步代码,从而提高性能呢?
所以下面我们介绍一下单例模式懒汉式双重校验锁

public class Singleton {
	/**
	 * 懒汉式变种,属于懒汉式中最好的写法,保证了:延迟加载和线程安全
	 */
	private static Singleton instance=null;
	
	private Singleton() {};
	
	public static Singleton getInstance(){
		 if (instance == null) {  
	          synchronized (Singleton.class) {  
	              if (instance == null) {  
	            	  instance = new Singleton();  
	              }  
	          }  
	      }  
	      return instance;  
	}
}

这种方法线程安全并且效率较高,是比较推荐使用的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

电脑小白路过

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值