单例模式

核心作用:
保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。

实例:
1.Windows中的任务管理器 2.回收站……

优点:
只生成一个实例,减小了系统性能的开销
 

五种单例模式的实现方式:
1、饿汉式(线程安全,调用效率高。但是,不能延时加载)
私有属性static类变量 先初始化(new 新对象)
私有的构造器
开放的方法--->取对象(方法无同步)
 

public class Demo01 {
	//类初始化时,立即加载这个对象。(没有延时加载优势)
	//天然线程安全
	private static Demo01 instance = new Demo01(); 
	
	private Demo01(){}
	
	//方法没有同步,调用效率高
	public static Demo01 getInstance(){
		return instance;
	} 
}

2、懒汉式(线程安全,调用效率不高。但是,可以延时加载)
私有属性static类变量 不用初始化
私有化构造器
开放方法-->取对象 使用方法时才检查初始化对象(new) (方法有同步)

public class Demo02 {
	//类初始化时,不初始化这个对象。(延时加载优势)
	//天然线程安全
	private static Demo02 instance ; 
	
	private Demo02(){}
	
	//方法同步,调用效率不高
	public static synchronized Demo02 getInstance(){
		if(instance==null){
			instance = new Demo02();
		}
		return instance;
	} 
}

3、双重检测锁式(由于JVM底层内部模型原因,偶尔会出现问题,不建议使用)
将同步内容放到下方的if内部
 

public class Demo03 {
	private Demo03(){}
	
	private static Demo03 instance=null;
	
	public static Demo03 getInstance() { 
	    if (instance == null) { 
	      Demo03 sc; 
	      synchronized (Demo03.class) { 
	        sc = instance; 
	        if (sc == null) { 
	          synchronized (Demo03.class) { 
	            if(sc == null) { 
	              sc = new Demo03(); 
	            } 
	          } 
	          instance = sc; 
	        } 
	      } 
	    } 
	    return instance; 
	  } 
}

4、静态内部类式(线程安全,调用效率高,但是,可以延时加载)
外部类没有static属性,不会像饿汉式那样立即加载对象
只有真正调用getInstance(),才会加载静态内部类。

public class Demo04 {
	private static class SingleTonClassInstance{
		private static final Demo04 instance = new Demo04();
	}
	
	public static Demo04 getInstance(){
		return SingleTonClassInstance.instance;
	}
	
	private Demo04(){}
}


5、枚举单例(线程安全,调用效率高,不能延时加载)
基于JVM实现的
可以天然防止反射和反序列化漏洞

public enum Demo05 {
	//这个枚举元素,本身就是单例对象!
	INSTANCE;
	
	//添加自己需要的操作!
	public void singletonOperation(){
		……
	}
}

 

需要延时加载:静态内部类好于饿汉式
不需要延时加载:静态内部类好于懒汉式

 

测试懒汉式单例模式(如何防止反射和反序列化漏洞):

public class Demo06 implements Serializable{
	//类初始化时,不初始化这个对象。(延时加载优势)
	//天然线程安全
	private static Demo06 instance ; 
	
	private Demo06(){
		//通过这样防止反射创建新的对象
		if(instance!=null){
			throw new RuntimeException();
		}
	}
	
	//方法同步,调用效率不高
	public static synchronized Demo06 getInstance(){
		if(instance==null){
			instance = new Demo06();
		}
		return instance;
	} 
	
	//反序列化时,如果定义了readResolve()方法则直接返回方法指定对象。而不再单独创建新的对象
	private Object readResolve() throws ObjectStreamException{
		return instance;
	}
}

 

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值