亲爱的朋友们,大家好!
今天是 CSDN博客之星 投票的开始日!非常感谢你们在过去的时间里给予我无私的支持和鼓励,这一路走来,正是因为有你们的帮助,我才能不断进步,走得更远。
目前,投票已正式开启(2月14日到2月20日,一共七天,每天都可以投 ),如果你们愿意支持我,可以通过以下链接给67号进行投票:

我非常珍惜你们的每一份支持,这对我意义重大,也将是我不断前进的动力!如果你们能为我投上宝贵的一票,我会更加努力,继续为大家带来更多有价值的技术分享。另外,这是我半年时间自研的 Java 框架 Sunrays-Framework:
如果有兴趣,欢迎随时取用!
再次感谢大家的支持与鼓励,期待我们一起成长!
文章目录
1.单例模式饿汉式(静态变量)
java
package com.sunxiansheng.design_pattern.singleton;
/**
* Description: 单例模式饿汉式(静态变量)
*
* @Author sun
* @Create 2025/1/17 15:12
* @Version 1.0
*/
public class TypeA {
public static void main(String[] args) {
Singleton singletonA = Singleton.getInstance();
Singleton singletonB = Singleton.getInstance();
System.out.println(singletonA == singletonB);
}
}
class Singleton {
/**
* 构造器私有化
*/
private Singleton() {
}
/**
* 静态变量
*/
private static final Singleton INSTANCE = new Singleton();
/**
* 暴露单例对象
*
* @return
*/
public static Singleton getInstance() {
return INSTANCE;
}
}
2.单例模式饿汉式(静态代码块)
java
package com.sunxiansheng.design_pattern.singleton.TypeB;
/**
* Description: 单例模式饿汉式(静态代码块)
*
* @Author sun
* @Create 2025/1/17 15:15
* @Version 1.0
*/
public class TypeB {
public static void main(String[] args) {
Singleton singletonA = Singleton.getInstance();
Singleton singletonB = Singleton.getInstance();
System.out.println(singletonB == singletonB);
}
}
class Singleton {
/**
* 构造器私有化
*/
private Singleton() {
}
/**
* 静态单例对象声明
*/
private static Singleton INSTANCE;
/**
* 静态代码块初始化单例对象
*/
static {
INSTANCE = new Singleton();
}
/**
* 向外暴露单例对象
*
* @return
*/
public static Singleton getInstance() {
return INSTANCE;
}
}
3.单例模式懒汉式(线程不安全)
java
package com.sunxiansheng.design_pattern.singleton.TypeC;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Description: 单例模式懒汉式(线程不安全)
*
* @Author sun
* @Create 2025/1/17 15:22
* @Version 1.0
*/
public class TypeC {
}
class Singleton {
/**
* 构造器私有化
*/
private Singleton() {
}
/**
* 静态变量
*/
private static Singleton INSTANCE;
/**
* 对外暴露单例对象
*
* @return
*/
public static Singleton getInstance() {
// 只有当静态变量为空的时候才赋值
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
4.单例模式懒汉式(同步方法)
java
package com.sunxiansheng.design_pattern.singleton.TypeD;
/**
* Description: 单例模式懒汉式(同步方法)
*
* @Author sun
* @Create 2025/1/17 15:36
* @Version 1.0
*/
public class TypeD {
}
class Singleton {
/**
* 构造器私有化
*/
private Singleton() {
}
/**
* 静态属性
*/
private static Singleton INSTANCE;
/**
* 同步方法,保证线程安全
*
* @return
*/
public synchronized static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
5.单例模式饿汉式(同步代码块,线程不安全)
java
package com.sunxiansheng.design_pattern.singleton.TypeE;
/**
* Description: 单例模式饿汉式(同步代码块,线程不安全)
*
* @Author sun
* @Create 2025/1/22 15:15
* @Version 1.0
*/
public class TypeE {
}
class Singleton {
/**
* 构造器私有化
*/
private Singleton() {
}
/**
* 静态变量
*/
private static Singleton singleton;
/**
* 向外暴露单例对象
*
* @return
*/
public static Singleton getInstance() {
if (singleton == null) {
// 使用一个同步代码块来解决
synchronized (Singleton.class) {
singleton = new Singleton();
}
}
return singleton;
}
}
6.单例模式懒汉式(双检锁)
java
package com.sunxiansheng.design_pattern.singleton.TypeF;
/**
* Description: 单例模式懒汉式(双检锁)
*
* @Author sun
* @Create 2025/1/22 15:25
* @Version 1.0
*/
public class TypeF {
}
class Singleton {
/**
* 构造器私有化
*/
private Singleton() {
}
/**
* 静态变量,volatile保证可见性
*/
private static volatile Singleton instance;
/**
* 向外暴露单例对象
*
* @return
*/
public static Singleton getInstance() {
// 1.判空
if (instance == null) {
// 2.加锁
synchronized (Singleton.class) {
// 3.再判空
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
7.单例模式懒汉式(静态内部类)
java
package com.sunxiansheng.design_pattern.singleton.TypeG;
/**
* Description: 单例模式懒汉式(静态内部类)
*
* @Author sun
* @Create 2025/1/22 15:35
* @Version 1.0
*/
public class TypeG {
}
class Singleton {
/**
* 构造器私有化
*/
private Singleton() {
}
/**
* 静态内部类,里面有一个静态常量
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
/**
* 暴露方法,加载静态内部类,并获取对象
*
* @return
*/
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
8.单例模式饿汉式(枚举实现)
java
package com.sunxiansheng.design_pattern.singleton.TypeH;
/**
* Description: 单例模式饿汉式(枚举实现)
*
* @Author sun
* @Create 2025/1/22 15:42
* @Version 1.0
*/
public class TypeH {
}
enum Singleton {
/**
* 天生的单例对象
*/
SINGLETON(1, "sun")
;
private int age;
private String name;
/**
* 构造器默认是私有化的
*
* @param age
* @param name
*/
Singleton(int age, String name) {
this.age = age;
this.name = name;
}
}
9.总结
单例模式共有八种,其中包含几种典型错误!
第一种是通过静态变量来实现,也就是利用了类只加载一次的特性去完成的。
第二种是通过静态代码块来实现对静态变量的赋值,本质跟第一种没有区别。
第三种是想要实现一个懒汉式,就直接判断变量不为空的时候再赋值,但是会有线程安全问题。
第四种是为了保证线程安全,就采用了同步方法,这样虽然可以解决问题,但是锁的粒度太大。
第五种是为了降低锁的粒度,想要使用同步代码块加在创建实例的部分,但是是没用的,因为可以有多个线程同时判断变量为空,从而进来创建对象,这样做只能保证按照顺序的创建对象,并不能保证不会多次创建对象。
第六种就是既可以降低锁的粒度又可以保证线程安全的双检锁,采用判空,加锁,再判空的方式来完成单例对象的创建。
第七种是静态内部类的方式,就是编写一个静态内部类,持有着静态常量,类加载并不会加载静态内部类,所以外部类在需要的时候去拿这个单例对象即可。
第八种是枚举实现,枚举可以说是最佳的单例实现方式,只要只创建一个枚举对象,那么就是单例的了。