一、单例设计模式
1.1、概述
单例模式(Singleton Pattern)是Java中最简单的设计模式之一。这种类型的设计模式属于创建者模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
1.2、应用场景
只需要一个实例,例如:各种Manager、各种Factory
二、单例模式的结构
2.1、单例模式主要有以下角色
- 单例类:只能创建一个实例的类
- 访问类:使用单例类
2.2、单例模式的实现
- 饿汉式:类加载就会导致该单例对象被创建
- 懒汉式:类加载不会导致该单例对象被创建,当首次使用该对象时才会创建
2.3、单例模式-饿汉式
2.3.1、静态成员变量
/**
* @Author : 一叶浮萍归大海
* @Date: 2024/2/25 22:51
* @Model Description:
* @Description: 单例模式饿汉式:静态成员变量
* @特点:类加载就会导致该单例对象被创建
* 存在的问题:由于对象的创建是随着类的加载而创建,所以存在内存浪费的问题。
*/
public class HungryManDemo1 {
/**
* 1、私有构造方法
*/
private HungryManDemo1() {
System.out.println(Thread.currentThread().getName() + "\t 构造方法SingletonDemo1被调用了");
}
/**
* 2、在当前类中创建本类对象
*/
private static HungryManDemo1 instance = new HungryManDemo1();
/**
* 3、对外提供获取本类实例对象的公共访问方式
* @return
*/
public static HungryManDemo1 getInstance() {
return instance;
}
}
2.3.2、静态代码块
/**
* @Author : 一叶浮萍归大海
* @Date: 2024/2/25 22:51
* @Model Description:
* @Description: 单例模式饿汉式:静态代码块
* @特点:类加载就会导致该单例对象被创建
* 存在的问题:由于对象的创建是随着类的加载而创建,所以存在内存浪费的问题。
*/
public class HungryManDemo2 {
/**
* 1、私有构造方法
*/
private HungryManDemo2() {
System.out.println(Thread.currentThread().getName() + "\t 无参构造方法SingletonDemo2()被调用了");
}
/**
* 2、在当前类中创建本类对象
*/
private static HungryManDemo2 instance;
/**
* 3、在静态代码块中进行赋值
*/
static {
instance = new HungryManDemo2();
}
/**
* 4、对外提供获取本类实例对象的公共访问方式
* @return
*/
public static HungryManDemo2 getInstance() {
return instance;
}
}
2.3.3、存在的问题
由于对象的创建是随着类的加载而创建,所以存在内存浪费的问题。
2.4、单例模式-懒汉式
2.4.1、线程不安全
/**
* @Author : 一叶浮萍归大海
* @Date: 2024/2/25 23:27
* @Model Description:
* @Description: 单例模式懒汉式:静态成员变量
* 存在的问题:多线程情况下,会创建多个实例
*/
public class LazyManDemo1 {
/**
* 1、私有构造方法
*/
private LazyManDemo1() {
System.out.println(Thread.currentThread().getName() + "\t 我是构造方法LazyManDemo1()");
}
/**
* 2、在当前类中声明当前类的类型变量
* 这是声明了一个该类型的变量,并没有进行赋值
*/
private static LazyManDemo1 instance;
/**
* 3、对外提供获取该类对象的方法
* @return
*/
public static LazyManDemo1 getInstance() {
if (instance == null) {
instance = new LazyManDemo1();
}
return instance;
}
}
2.4.2、线程安全
/**
* @Author : 一叶浮萍归大海
* @Date: 2024/2/25 23:27
* @Model Description:
* @Description: 单例模式懒汉式:静态成员变量
*/
public class LazyManDemo2 {
/**
* 1、私有构造方法
*/
private LazyManDemo2() {
System.out.println(Thread.currentThread().getName() + "\t 我是构造方法LazyManDemo2()");
}
/**
* 2、在当前类中声明当前类的类型变量
* 这是声明了一个该类型的变量,并没有进行赋值
*/
private static LazyManDemo2 instance;
/**
* 3、对外提供获取该类对象的方法
* @return
*/
public synchronized static LazyManDemo2 getInstance() {
if (instance == null) {
instance = new LazyManDemo2();
}
return instance;
}
}
2.4.3、双重锁检查机制【推荐】
/**
* @Author : 一叶浮萍归大海
* @Date: 2024/2/25 23:27
* @Model Description:
* @Description: 单例模式懒汉式:静态成员变量
* 双重检查锁模式,保证线程安全
*/
public class LazyManDemo3 {
/**
* 1、私有构造方法
*/
private LazyManDemo3() {
System.out.println(Thread.currentThread().getName() + "\t 我是构造方法LazyManDemo3()");
}
/**
* 2、在当前类中声明当前类的类型变量
* 这是声明了一个该类型的变量,并没有进行赋值
*/
private static volatile LazyManDemo3 instance;
/**
* 3、对外提供获取该类对象的方法
* @return
*/
public synchronized static LazyManDemo3 getInstance() {
if (instance == null) {
synchronized (LazyManDemo3.class) {
if (instance == null) {
instance = new LazyManDemo3();
}
}
}
return instance;
}
}
101万+

被折叠的 条评论
为什么被折叠?



