Java全栈面试宝典:锁机制与Spring生命周期深度解析
目录
一、synchronized锁状态机全解析
🔥 问题5:synchronized四态转换与性能对比
锁状态转换流程图
锁特性对比表
CAS操作示例
二、ReentrantLock与synchronized深度对比
🔥 问题6:两大锁机制对比
核心差异矩阵
生产级ReentrantLock示例
三、Spring Bean生命周期与装配机制
🌟 Bean生命周期关键方法
生命周期流程图
关键方法重载示例
🌟 Spring集合注入与自动装配
集合注入示例
自动装配模式对比
四、高频面试题强化训练
1. 如何选择synchronized和ReentrantLock?
2. Bean生命周期回调执行顺序?
3. 自动装配的歧义性如何解决?
一、synchronized锁状态机全解析
🔥 问题5:synchronized四态转换与性能对比
锁状态转换流程图
锁特性对比表
锁类型 | 优点 | 缺点 | 适用场景 | JVM参数 |
---|---|---|---|---|
偏向锁 | 无CAS开销,单线程零成本 | 撤销需要暂停线程 | 单线程独占场景 | -XX:+UseBiasedLocking |
轻量级锁 | 线程不阻塞,响应快 | 自旋消耗CPU | 低竞争短同步 | 默认启用 |
重量级锁 | 不消耗CPU | 线程切换开销大 | 高竞争长同步 | 默认启用 |
CAS操作示例
// 轻量级锁获取伪代码
void enterLightweightLock() {
MarkWord mark = object.markWord;
if (mark.isNeutral()) { // 无锁状态
LockRecord lockRecord = thread.stack.createLockRecord();
lockRecord.displacedHeader = mark;
if (CAS(object.markWord, mark, lockRecord.address)) {
return; // 获取成功
}
}
// 升级为重量级锁
inflateLock();
}
二、ReentrantLock与synchronized深度对比
🔥 问题6:两大锁机制对比
核心差异矩阵
维度 | synchronized | ReentrantLock |
---|---|---|
实现级别 | JVM关键字 | JDK类实现 |
锁公平性 | 非公平 | 可选公平/非公平 |
条件队列 | 单队列 | 多Condition |
中断响应 | 不支持 | lockInterruptibly() |
锁绑定 | 自动释放 | 必须手动unlock() |
性能 | 优化后接近 | 高竞争更优 |
生产级ReentrantLock示例
public class BoundedBuffer {
private final ReentrantLock lock = new ReentrantLock(true); // 公平锁
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();
private final Object[] items = new Object[100];
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[count++] = x;
notEmpty.signal();
} finally {
lock.unlock();
}
}
}
三、Spring Bean生命周期与装配机制
🌟 Bean生命周期关键方法
生命周期流程图
关键方法重载示例
public class LifecycleBean implements
BeanNameAware, InitializingBean, DisposableBean {
@Override
public void setBeanName(String name) {
System.out.println("3. BeanName回调: " + name);
}
@PostConstruct
public void postConstruct() {
System.out.println("5. @PostConstruct");
}
@Override
public void afterPropertiesSet() {
System.out.println("6. InitializingBean");
}
public void customInit() {
System.out.println("7. 自定义init");
}
@PreDestroy
public void preDestroy() {
System.out.println("8. @PreDestroy");
}
@Override
public void destroy() {
System.out.println("9. DisposableBean");
}
public void customDestroy() {
System.out.println("10. 自定义destroy");
}
}
🌟 Spring集合注入与自动装配
集合注入示例
<bean id="complexObject" class="com.example.ComplexObject">
<property name="list">
<list>
<value>Java</value>
<ref bean="springBean"/>
</list>
</property>
<property name="map">
<map>
<entry key="key1" value="value1"/>
<entry key="key2" value-ref="springBean"/>
</map>
</property>
</bean>
运行 HTML
自动装配模式对比
模式 | 说明 | 注解示例 |
---|---|---|
byType | 按类型匹配 | @Autowired |
byName | 按名称匹配 | @Resource |
constructor | 构造器参数匹配 | 构造器参数上的@Autowired |
no | 默认不自动装配 | - |
四、高频面试题强化训练
1. 如何选择synchronized和ReentrantLock?
-
选择synchronized:简单同步场景、追求代码简洁性
-
选择ReentrantLock:需要公平锁、可中断锁、超时锁、条件队列等高级特性
2. Bean生命周期回调执行顺序?
-
构造函数
-
@Autowired注入
-
@PostConstruct
-
InitializingBean.afterPropertiesSet()
-
自定义init-method
-
@PreDestroy
-
DisposableBean.destroy()
-
自定义destroy-method
3. 自动装配的歧义性如何解决?
@Autowired
@Qualifier("mainDataSource")
private DataSource dataSource;
// 或使用JSR-250
@Resource(name="mainDataSource")
private DataSource dataSource;
实战建议:
-
使用
jstack
工具分析锁竞争情况 -
通过
@Order
控制Bean初始化顺序 -
使用
@Lazy
延迟初始化解决复杂依赖
💬 你在项目中遇到过哪些锁性能问题?如何优化的?
🎁 关注+转发,抽送《Java并发编程实战》电子书
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dtcms.com/a/115901.html
如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!