单例模式懒汉和饿汉,以及终极版懒汉

本文深入探讨单例模式的三种实现方式:懒汉模式、饿汉模式及线程安全版懒汉模式。懒汉模式在调用静态方法时创建对象,饿汉模式在类加载时即创建对象,线程安全版懒汉模式则通过synchronized确保多线程环境下的安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单例懒汉模式和饿汉模式,以及线程安全版懒汉模式

单例模式:是一种常见的设计模式,一个类只能创建出一个实例对象,这就是单例模式写法(封装)。
封装:就是对复杂事物的一种简化。可以说是对具有相同特征的一类事物进行抽象封装,抽象程度越高,封装就越彻底。这样有助于建立各个系统之间的低耦合关系,提高系统的独立性。其实封装并不是一种技术,而是一种思想。当一件事变得复杂,就需要从一个更高的层次来进行管理。
懒汉模式:在调用静态方法时才能创建对象
  1. 将构造器私有化。
  2. 一个静态私有属性存放当前类常量的对象变量。
  3. 提供一个公有的静态方法,获取到之前对象变量。
    懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的
package im;

/**

- 懒汉模式
- @author MF
*
 */
public class Person {
  private static Person person; 
  private Person() {	
}
  public static Person getPerson() {
	if(person == null) {
		person=new Person();
		
      }
      return person;
  }

}

饿汉模式:类加载完成就创建对象
  1. 将构造器私有化。
  2. 私有静态属性中存放创建的对象,并且在类加载完成就创建好了。
  3. 提供一个公有的静态方法,获取之前对象变量。
    饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以是线程安全的。
package im;

/**
  *  饿汉模式
 * @author MF
 *
 */
public class Person2 {
	
	private static Person2 person =new Person2();
	
	private Person2() {
	}
	public static Person2 getPerson() {
		return person;
	}

}

线程安全版懒汉模式 利用synchronized作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
package im;

import java.util.concurrent.locks.ReentrantLock;

public class Person3 {
	
	private static volatile Person3 p;//保证了原子性,一致性
	//private static ReentrantLock lock =new ReentrantLock();
	
	private Person3() { System.out.println(5);
	}
	
	public static Person3 getPerson() {
		if(p==null) {//如果对象存在,直接返回,不需要进行等待了,直接返回,效率高
			synchronized (Person.class) {
				if(p==null) {
					p=new Person3();
				}
               /**
				 *  开辟空间                    1
				 *  赋初始值                    2 
				 *  返回地址给变量p              3
				 */
				
			}
		}
		return p;
		
	}

}

前几天被朋友说到,我的优快云是在一直摸鱼,一周就更新一篇,内容还少。emmmmm,我不是咸鱼,好吧。接下来我会提高自己的更新量和文章水平的。
在这里插入图片描述

### 单例模式懒汉式与饿汉式的区别及线程安全实现 #### 1. 饿汉单例模式 饿汉单例模式在类加载时完成实例化,因此在使用时无需再进行判断或加锁操作。这种模式的优点是实现简单、线程安全,缺点是可能会浪费内存资源,因为实例在程序启动时就已经创建[^3]。 以下是饿汉单例模式的实现代码: ```java public class Singleton { // 在类加载时直接初始化实例 private static final Singleton instance = new Singleton(); // 私有构造函数,防止外部实例化 private Singleton() {} // 提供全局访问点 public static Singleton getInstance() { return instance; // 直接返回已创建的实例 } } ``` 饿汉单例模式的特点包括: - 实例在类加载时创建[^1]。 - 线程安全,无需额外的同步机制[^2]。 - 内存占用较高,因为实例一旦创建就不会释放。 #### 2. 懒汉单例模式 懒汉单例模式在第一次调用 `getInstance()` 方法时才创建实例,因此可以延迟实例化,节省内存资源。然而,由于多线程环境下可能存在并发问题,需要通过同步机制来保证线程安全[^4]。 以下是懒汉单例模式的实现代码(线程不安全版本): ```java public class Singleton { private static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { // 第一次检查 instance = new Singleton(); // 可能存在线程安全问题 } return instance; } } ``` 为了解决线程安全问题,可以通过双重检查锁定(Double-Checked Locking)来优化懒汉单例模式: ```java public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { // 第一次检查 synchronized (Singleton.class) { if (instance == null) { // 第二次检查 instance = new Singleton(); // 创建实例 } } } return instance; } } ``` 懒汉单例模式的特点包括: - 实例在第一次调用 `getInstance()` 方法时创建。 - 内存使用效率较高,因为只有在需要时才会创建实例。 - 需要额外的同步机制来保证线程安全[^4]。 #### 3. 区别总结 | 特性 | 饿汉单例模式 | 懒汉单例模式 | |------------------|-------------------------------|------------------------------------| | 实例化时机 | 类加载时 | 第一次调用 `getInstance()` 时 | | 线程安全性 | 天然线程安全 | 需要额外的同步机制 | | 内存使用 | 较高,实例始终占用内存 | 较低,仅在需要时创建实例 | | 实现复杂度 | 简单 | 较复杂,需考虑线程安全问题 | #### 4. 应用场景 单例模式适用于以下场景: - 系统只需要一个实例对象时,例如日志模块、线程池模块等。 - 资源消耗较大而只允许创建一个对象时。 - 客户端需要通过公共访问点访问同一实例时。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值