首页 > 其他分享 >设计模式(1)-单例模式

设计模式(1)-单例模式

时间:2023-07-25 21:44:17浏览次数:39  
标签:静态 模式 LazyMan static private 单例 new 设计模式 public

单例模式


饿汉式
懒汉式
懒汉双加锁
静态内部类
C#特有写法
破坏单例

  • 定义:有且仅有一个实例,节省资源。
  • 构造函数私有化
  • 静态只读私有字段
  • 静态公开的获取私有字段的方法

饿汉式

public class HungryMan
{
// 构造函数私有化
  private HungryMan() { }

// 静态只读私有字段
  private readonly static HungryMan _HungryMan = new HungryMan();

// 静态获取私有字段的方法,也可以写个属性
  public static HungryMan GetHungryMan() 
  {
  	return _HungryMan;
  }
}
问题:
  • 由于有静态字段,所以程序加载静态字段就加载,即使目前用不到,他也会加载,所以有一定的资源浪费。

懒汉式

public class LazyMan
{
   private LazyMan() { }// 构造函数私有化

   private static LazyMan _LazyMan;// 私有字段
   public static LazyMan GetLazzyMan() // 静态获取私有字段的方法
   {
   	if (_LazyMan==null)
   	{
   		_LazyMan = new LazyMan();
   	}		
   	return _LazyMan;
   }
}
问题
  • 线程不安全,可能同时有多个线程同时进入if中
改造
  • 加一个互斥锁
public class LazyMan
{
	private LazyMan() { }// 构造函数私有化

	private static LazyMan _LazyMan;// 私有字段
	private static object o = new object();
	public static LazyMan GetLazzyMan() // 静态获取私有字段的方法
	{
		lock (o)// 互斥锁,只允许一个线程进入。其实就是Monitor.Enter()  Monitor.Exit()
		{
			if (_LazyMan == null)
			{
				_LazyMan = new LazyMan();
			}

		}
		return _LazyMan;
	}
}
问题
  • 每次都进互斥锁,有额外性能开销
  • _LazyMan = new LazyMan();的正常顺序为:
  • 1.开辟内存空间
  • 2.创建一个对象
  • 3.对象指向内存空间
  • 可能会有极端情况使123乱序为132,即指针重排,所以字段加volatile关键字

改造:饿汉双加锁

public class LazyMan
{
   private LazyMan() { }// 构造函数私有化

   private volatile static LazyMan _LazyMan;// 私有字段,加volatile
   private static object o = new object();
   public static LazyMan GetLazzyMan() // 静态获取私有字段的方法
   {
   	if (_LazyMan == null)
   	{
   		lock (o)// 互斥锁,只允许一个线程进入。其实就是Monitor.Enter()Monitor.Exit()
   		{
   			if (_LazyMan == null)
   			{
   				_LazyMan = new LazyMan();
   			}
   		}
   	}
   	return _LazyMan;
   }
}

静态内部类改造饿汉式

public class HungryStaticMan
{
   private HungryStaticMan() {}
   // 静态内部类
   public static class InnerClass
   {
   	public static HungryStaticMan _HungryStaticMan=new HungryStaticMan();
   }
   // 静态获取方法
   public static HungryStaticMan GetStaticMan()
   {
   	return InnerClass._HungryStaticMan;
   }
}
优点
* 用的时候创建,不会浪费空间

C#提供的懒汉式

public class SampleLazyMan
{
	private SampleLazyMan() {}
	
	private static readonly Lazy<SampleLazyMan> Lazy=new Lazy<SampleLazyMan>(()=>new SampleLazyMan());
	
	public SampleLazyMan GetLazyMan()
	{
		return Lazy.Value;
	}
}
优点
  • 线程安全

破坏单例

用反射,获取单例的构造函数。可以在单例的构造函数中加标志位避免,但标志位同样可以在单例中获取,所以“防君子不防小人”。

标签:静态,模式,LazyMan,static,private,单例,new,设计模式,public
From: https://www.cnblogs.com/Hanwen680/p/17566565.html

相关文章

  • python单例类
    Python单例类的实现方法概述在Python中,单例模式是一种常见的设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。在某些情况下,需要确保一个类的对象在整个程序中只被创建一次,以避免资源的浪费。本文将介绍如何在Python中实现单例类,并提供一个详细的步骤,以便新手开发者能够......
  • 23种设计模式介绍
    面向对象23种设计模式设计模式的分类按意图分类接口型模式职责型模式构造型模式操作型模式扩展型模式意图模式接口型模式适配器模式、外观模式、合成模式、桥接模式职责型模式代理模式,享元模式、单例模式、观察者模式、调停者模式、职责链模式构造型模......
  • 利用策略模式结合Springboot框架
    利用策略模式解决多条件问题问题重现这是公司代码里面的一个接口,我需要根据type的不同,去决定要不要存储里面的对象。ini复制代码@Transactional(rollbackFor=Exception.class)@OverridepublicbooleansaveDimensionsByQuestionBankId(List<MbDimensionsDto>dimensio......
  • 设计模式-职责链模式在Java中使用示例-采购审批系统
    场景采购单分级审批采购审批是分级进行的,即根据采购金额的不同由不同层次的主管人员来审批,主任可以审批5万元以下(不包括5万元)的采购单,副董事长可以审批5万元至10万元(不包括10万元)的采购单,董事长可以审批10万元至50万元(不包括50万元)的采购单,50万元及以上的采购单就需要开董事会......
  • .NET(C#) 设计模式
    .NET(C#)设计模式简介设计模式(Designpattern)是代码设计经验的总结。设计模式主要分三个类型:创建型、结构型和行为型。创建型是对象实例化的模式,创建型模式用于解耦对象的实例化过程,主要用于创建对象。结构型是把类或对象结合在一起形成一个更大的结构,主要用于优化不同类、对......
  • 设计模式—享元模式
    享元模式享元模式(FlyweightPattern)是池技术的重要实现方式,其定义如下:Usesharingtosupportlargenumbersoffine-grainedobjectsefficiently.(使用共享对象可有效地支持大量的细粒度的对象。)优点与缺点享元模式是一个非常简单的模式,它可以大大减少应用程序创建的对象,降......
  • 设计模式—组合模式
    组合模式目录组合模式优点缺点使用场景注意事项例子组合模式(CompositePattern)也叫合成模式,有时又叫做部分-整体模式(Part-Whole),主要是用来描述部分与整体的关系。将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。优点......
  • 设计模式—状态模式
    状态模式目录状态模式优点缺点适用场景注意事项通用类图例子状态模式与策略模式的差异当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。状态模式的核心是封装,状态的变更引起了行为的变更,从外部看起来就好像这个对象对应的类发生了改变一样。优点结构清......
  • 设计模式—中介者模式
    中介者模式目录中介者模式优点缺点适用场景中介者模式与外观模式差异用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。优点减少类之间的依赖,将原有的一对多的依赖变成一对一的依赖,同事类只依赖中......
  • 设计模式—单例模式
    目录优点缺点使用场景注意事项案例分析定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。优点由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁地创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就非常明显。由......