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

单例设计

一、单例设计

        Singleton类中永远只会有一个实例化对象,此种代码实现的根本原理就是在于将一个类的构造方法关闭了。

        当一个类中只能产生一个实例化对象的时候,就需要将构造方法封闭,封闭之后的操作通过一个静态方法取得本类的实例化对象。

      1. 构造方法私有化
      2. 本类的一个静态实例
      3. 提供一个静态方法获得本类的实例化对象

 如果要想继续划分的,实际上单例设计,还分成两种类型:

                  ·懒汉式:当第一次使用本类的对象时,在进行对象的实例化操作。

                  ·饿汉式:一个单例类中不管是否使用,都始终维护一个实例化对象。

二、懒汉式

class Singleton {

         private static Singleton instance =  null ;

         public static Singleton  getInstance(){       // 将instance传递到外部去

                   if(instance  == null){

                            instance  = new Singleton() ;

                   }

                   return  instance ;

         }

         private Singleton(){}

         public void print(){

                   System.out.println("Hello  World!!!") ;

         }

};

public class  Test{ 

         public static void main(String  args[]){

                   Singleton s1 =  Singleton.getInstance() ;

                   Singleton s2 =  Singleton.getInstance() ;

                   Singleton s3 =  Singleton.getInstance() ;

                   s1.print() ;

                   s2.print() ;

                   s3.print() ;

         }

};

三、饿汉式

class Singleton {

         private static final Singleton instance = new  Singleton() ;   // 在内部准备好一个对象

         public static Singleton getInstance(){       // 将instance传递到外部去

                   return instance ;

         }

         private Singleton(){}

         public void print(){

                   System.out.println("Hello  World!!!") ;

         }

};

public class  Test{ 

         public static void main(String  args[]){

                   Singleton s1 =  Singleton.getInstance() ;

                   Singleton s2 =  Singleton.getInstance() ;

                   Singleton s3 =  Singleton.getInstance() ;

                   s1.print() ;

                   s2.print() ;

                   s3.print() ;

         }

};

四、单例模式的风险

单例模式很简单,就是在构造函数中多了加一个构造函数,访问权限是private的就可以了,这个模式是简单,但是简单中透着风险,风险?什么风险?在一个B/S项目中,每个HTTP Request请求到J2EE的容器上后都创建了一个线程,每个线程都要创建同一个单例对象,假如现在有两个线程A和线程B,线程A执行到 instance  = new Singleton() ;正在申请内存分配,可能需要0.001微秒,就在这0.001微秒之内,线程B执行到if(instance  == null) 你说这个时候这个判断条件是true还是false?是true,那然后呢?线程B也往下走,于是乎就在内存中就有两个Singleton的实例了,看看是不是出问题了?
如果你这个单例是去拿一个序列号或者创建一个信号资源的时候,会怎么样?业务逻辑混乱!数据一致性校验失败!最重要的是你从代码上还看不出什么问题,这才是最要命的!因为这种情况基本上你是重现不了的,不寒而栗吧,那怎么修改?

public class Singleton {
	private static final Singleton singleton = new Singleton();

	//限制住不能直接产生一个实例
	private Singleton() {
	}

	public synchronized static Singleton getInstance() {
		return singleton;
	}
}


饿汉式+synchronized ?


 

 

posted on   小强斋太  阅读(180)  评论(0编辑  收藏  举报

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律

导航

< 2013年5月 >
28 29 30 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 1
2 3 4 5 6 7 8
点击右上角即可分享
微信分享提示