目录
[🔥 问题9:notify与notifyAll的底层差异](#🔥 问题9:notify与notifyAll的底层差异)
[🔥 问题10:yield()方法的三大使用原则](#🔥 问题10:yield()方法的三大使用原则)
[🔥 问题11:现代线程中断机制](#🔥 问题11:现代线程中断机制)
[二、Spring Bean管理全景解析](#二、Spring Bean管理全景解析)
[🌟 Spring Bean核心概念](#🌟 Spring Bean核心概念)
[🌟 Spring配置方式对比](#🌟 Spring配置方式对比)
[🌟 Bean作用域详解](#🌟 Bean作用域详解)
[1. BeanFactory与ApplicationContext的区别?](#1. BeanFactory与ApplicationContext的区别?)
[2. 如何解决构造器注入循环依赖?](#2. 如何解决构造器注入循环依赖?)
[3. @Autowired与@Resource的区别?](#3. @Autowired与@Resource的区别?)
一、Java线程协作核心机制
🔥 问题9:notify与notifyAll的底层差异
对象监视器模型

核心差异对比表
方法 | 影响范围 | 锁竞争 | 适用场景 |
---|---|---|---|
notify() | 随机唤醒一个等待线程 | 单线程竞争 | 精确控制唤醒对象 |
notifyAll() | 唤醒所有等待线程 | 多线程竞争 | 避免线程饥饿 |
代码验证示例
java
public class NotifyDemo {
private static final Object lock = new Object();
public static void main(String[] args) {
IntStream.range(0, 3).forEach(i -> new Thread(() -> {
synchronized (lock) {
try {
System.out.println("线程" + i + "进入等待");
lock.wait();
System.out.println("线程" + i + "被唤醒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start());
new Thread(() -> {
synchronized (lock) {
lock.notify(); // 仅唤醒一个线程
// lock.notifyAll(); // 唤醒所有线程
}
}).start();
}
}
🔥 问题10:yield()方法的三大使用原则
方法特性解析
-
提示性:仅建议调度器让出CPU,不保证立即切换
-
非阻塞性:不会释放已持有的锁资源
-
适用场景:
-
调试多线程竞争问题
-
实现协作式多任务
-
自定义并发控制结构
-
代码示例
java
public class YieldDemo {
public static void main(String[] args) {
new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("线程A运行");
Thread.yield();
}
}).start();
new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("线程B运行");
}
}).start();
}
}
🔥 问题11:现代线程中断机制
中断处理最佳实践

正确中断代码模板
java
public class ThreadInterruptDemo {
public static void main(String[] args) throws InterruptedException {
Thread worker = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
// 模拟工作
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
// 重置中断状态
Thread.currentThread().interrupt();
System.out.println("处理中断请求");
}
}
System.out.println("线程优雅终止");
});
worker.start();
TimeUnit.SECONDS.sleep(1);
worker.interrupt();
}
}
二、Spring Bean管理全景解析
🌟 Spring Bean核心概念
Bean定义要素
配置维度 | 说明 | 示例 |
---|---|---|
类全限定名 | Bean的实现类 | com.example.UserService |
作用域 | Bean的生命周期范围 | singleton/prototype |
初始化方法 | Bean创建后的回调方法 | initMethod="initialize" |
依赖关系 | 需要注入的其他Bean | <property name="dao" ref="userDao"/> |
延迟初始化 | 是否延迟创建Bean实例 | lazy-init="true" |
🌟 Spring配置方式对比
配置方式矩阵
方式 | 实现示例 | 优点 | 缺点 |
---|---|---|---|
XML配置 | <bean id="user" class="com.User"/> |
集中管理 | 冗长 |
注解驱动 | @Component |
简洁快速 | 配置分散 |
Java Config | @Bean 注解方法 |
类型安全 | 需要编码 |
Groovy DSL | beans { user(User) } |
动态灵活 | 学习成本高 |
XML注入方式示例
xml
XML
<!-- 构造器注入 -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<constructor-arg ref="config"/>
</bean>
<!-- Setter注入 -->
<bean id="userService" class="com.example.UserService">
<property name="userDao" ref="userDao"/>
</bean>
<!-- 工厂方法注入 -->
<bean id="calendar" class="java.util.Calendar"
factory-method="getInstance"/>
🌟 Bean作用域详解
作用域类型表
作用域 | 说明 | 适用场景 |
---|---|---|
singleton | 单例(默认) | 无状态服务 |
prototype | 每次获取新实例 | 有状态对象 |
request | 每个HTTP请求独立实例 | Web请求上下文 |
session | 用户会话生命周期 | 用户会话数据 |
application | ServletContext生命周期 | 全局共享资源 |
websocket | WebSocket会话生命周期 | 实时通信场景 |
作用域配置示例
java
@Configuration
public class AppConfig {
@Bean
@Scope("prototype")
public PrototypeBean prototypeBean() {
return new PrototypeBean();
}
@Bean
@RequestScope
public RequestBean requestBean() {
return new RequestBean();
}
}
三、高频面试题强化训练
1. BeanFactory与ApplicationContext的区别?
功能 | BeanFactory | ApplicationContext |
---|---|---|
Bean实例化时机 | 延迟初始化 | 预初始化 |
国际化支持 | 不支持 | 支持MessageSource |
事件发布 | 不支持 | 支持ApplicationEvent |
资源访问 | 基础ResourceLoader | 增强资源模式匹配 |
AOP支持 | 需手动配置 | 自动代理生成 |
2. 如何解决构造器注入循环依赖?

3. @Autowired与@Resource的区别?
维度 | @Autowired | @Resource |
---|---|---|
来源 | Spring框架 | JSR-250标准 |
默认注入策略 | 按类型 | 按名称 |
必需性控制 | required=false | 无 |
适用目标 | 构造器/字段/方法 | 字段/setter方法 |
名称指定方式 | @Qualifier | name属性 |
实战建议:
-
使用
@Profile
实现环境特定配置 -
通过
BeanPostProcessor
实现自定义初始化逻辑 -
结合
@Conditional
实现条件化Bean注册
💬 你在项目中如何处理复杂的Bean依赖关系?遇到过哪些有趣的配置问题?
🎁 关注+转发,抽送《Spring揭秘》电子书