当前位置: 首页 > news >正文

八股整理xdsm - 教程

1.实现线程安全的单例模式

一、第一次检查:​​避免不必要的同步(提高性能)​

  • ​目的​​:在​​大多数情况下,实例已经被创建了​​,我们​​不希望每次调用 getInstance()都进入同步块​​,因为同步(即 synchronized)是有性能开销的。

  • 如果 ​​instance 已经不为 null​​,说明单例已经创建,那么​​直接返回即可,不需进入 synchronized 块​​,避免了线程排队等待锁,提升了性能。

二、第二次检查:​​确保单例只被创建一次(线程安全

  • 进入 synchronized 块的线程可能有多个(在第一次检查都发现 instance == null 的情况下)。

  • ​第一个进入同步块的线程​​会创建实例,但​​后面其他线程可能在等待锁释放后,也进入同步块​​。

  • 如果​​没有第二次检查​​,这些线程会​​再次创建新的实例​​,导致单例模式失效。

​双重检查锁(Double-Checked Locking, DCL)​​ 实现线程安全的​​懒汉式单例模式​

public class Singleton {
// volatile 保证可见性与禁止指令重排
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;
}
}

2.怎样自定义一个类加载器

先复习一下类加载器的关键方法:

核心方法:

  • ClassLoader.loadClass(String name)

    • 加载指定类名的类,​​默认实现遵循双亲委派机制​​。

    • 该途径内部会先委派给父类加载器,父类加载不了才自己尝试加载。

  • ClassLoader.findClass(String name)

    • ​真正去查找并定义一个类​​的方法,​​默认实现是抛出 ClassNotFoundException​​。

    • ​自定义类加载器通常重写该方法!​

  • ClassLoader.defineClass(byte[] b, int off, int len)

    • ​将字节数组(.class 材料的内容)转换为 Class 对象​​,这是 JVM 提供的一个 native 途径,​​一般由 findClass 调用​​。

步骤 1:继承 ClassLoader

通常你只需要继承 ClassLoader(或者 URLClassLoader,如果你想基于路径/URL 加载),然后​​重写 findClass(String name)方法​

步骤 2:实现 findClass方法

在这个方法中,你要求:

  1. ​根据类名,找到对应的 .class 材料(或字节码来源:文件、网络、内存、加密文件等)​

  2. ​读取该文件的字节码(byte[])​

  3. ​调用 defineClass(name, byte[], offset, length)方法,将字节数组转为 Class 对象​

3.SPI

SPI(Service Provider Interface,服务提供者接口)​​ 是 Java 提供的一种​​服务发现机制​​,它定义了一种 ​​“接口与建立相分离”​​ 的规范,允许 ​​第三方为某个接口提供具体实现​​,并在运行时​​动态地被发现和加载​​。

JDBC 是 SPI 的典型应用场景

1. JDBC 定义了一个标准接口

java.sql.Driver

这是由 ​​JDK 提供的接口​​,它定义了连接数据库的标准方法,比如 connect()

但它并没有提供具体实现,比如连接 MySQL、Oracle 的代码。

2. 各数据库厂商提供构建:

比如:

  • MySQL 提供了 com.mysql.cj.jdbc.Driver

  • Oracle 提供了 oracle.jdbc.driver.OracleDriver

这些类,就是 ​​SPI 的服务提供者实现(Service Provider)​​。

3. 但这些实现类不是由我们手动去 new 的,而是通过 ​​SPI 机制自动发现和加载的!​

关键点在于:​​MySQL 的 jar 包中有一个文件:​

​META-INF/services/java.sql.Driver

档案中就写了

com.mysql.cj.jdbc.Driver

它就告诉 JVM:“如果你想找一个 java.sql.Driver的实现,可以加载我这个类”。

​Java 在运行时通过 ServiceLoader找到这个配置,自动加载并实例化该驱动

http://www.jsqmd.com/news/256/

相关文章:

  • C++小白修仙记_LeetCode刷题_哈希表
  • 【F#学习】字符串String
  • US$98 Yanhua Mini ACDP Module4 BMW 35080, 35160DO WT EEPROM Read Write
  • US$98 Yanhua Mini ACDP Module4 BMW 35080, 35160DO WT EEPROM Read Write
  • 深入解析:K8s学习笔记(二) Pod入门与实战
  • 现代汽车前瞻杯2025牛客暑期多校训练营3
  • 详细介绍:[新启航]白光干涉仪在微透镜阵列微观 3D 轮廓测量中的应用解析
  • 实用指南:多技术融合提升环境生态水文、土地土壤、农业大气等领域的数据分析与项目科研水平
  • 【F#学习】“变量”?绑定!
  • 2023 CCPC 深圳 F
  • 完整教程:【算法】双指针(三)[快慢指针]-快乐数
  • 9.19做题资料:哈希表查找时间复杂度分析
  • CF2143F Increasing Xor
  • 提到链接,你能想到什么
  • 实用指南:容器逃逸漏洞
  • 实用指南:容器逃逸漏洞
  • 深入解析:卷对卷(Roll-to-Roll,R2R)技术的应用领域和技术进展
  • 三种方式处理SpringBoot全局异常
  • 解题记录说是 | P3695 CYaRon!语
  • 分享一个极度精简的绿色的 五笔输入法
  • [GDKOI2023 提高组] 游戏 题解
  • CSP-J/S 2025 游记
  • 2025.9.19 计数dp小记
  • 实用指南:AI推理范式:从CoT到ReAct再到ToT的进化之路
  • sign up - Gon
  • ctfshow web入门 信息搜集
  • 完整教程:数据结构:单链表的应用(力扣算法题)第二章
  • CF2039E Shohag Loves Inversions
  • 深入解析:sqlite3的加解密全过程
  • U522155 板垣 カノエ is WATCHING YOU std