### 并发面试专题知识点详解 #### 一、Synchronized的基本概念及原理 **Synchronized** 是Java语言中用于实现线程同步的关键字之一。它主要用于控制多个线程对共享资源的访问,确保同一时刻只有一个线程能够访问特定的代码段或者对象方法,从而避免数据竞争条件(race condition)的发生。 - **Synchronized关键字的应用场景**: - 修饰实例方法:作用于所属对象的锁,进入该方法前要获取所属对象的锁。 - 修饰静态方法:即给当前类加锁,锁的是当前类的所有对象。 - 修饰代码块:指定加锁对象,对给定对象加锁,执行代码块前需要获得给定对象的锁。 - **Synchronized的实现机制**: - 在JVM层面上,Synchronized是通过在对象头中设置标记的方式实现锁的获取和释放。具体来说,当一个线程尝试执行被Synchronized修饰的代码时,JVM会在字节码中插入`monitorenter`和`monitorexit`指令。 - `monitorenter`指令执行时,首先会尝试获取对象的锁;如果该对象没有被锁定或者当前线程已经拥有该对象的锁,则锁的计数器加1;反之,则当前线程将被阻塞,直到锁被释放。 - `monitorexit`指令执行时,锁计数器减1;当计数器为0时,锁被释放。 #### 二、Synchronized锁的工作原理深入解析 - **锁的本质**: - “锁”实际上是指`monitorenter`和`monitorexit`字节码指令的一个Reference类型的参数,即要锁定和解锁的对象。 - 当Synchronized修饰符明确指定了锁对象时,如`Synchronized(变量名)`或`Synchronized(this)`,那么加锁和解锁的对象就是指定的对象。 - 若Synchronized修饰的方法未明确指定锁对象,则依据以下规则确定: - 非静态方法:锁对象为所属对象自身。 - 静态方法:锁对象为所属类的Class对象。 - **可重入性**: - 可重入性指的是一个线程可以在已拥有某个锁的情况下再次获取该锁,而不会导致死锁。 - 在执行`monitorenter`指令时,如果当前线程已经拥有该对象的锁,则锁计数器递增1,这样就支持了锁的重入性。 - **锁的类型及其优化**: - **JVM锁优化**: - 自旋锁:在等待锁的过程中,线程先自旋等待一段时间,如果在这段时间内锁被释放,则避免了线程状态的切换。 - 锁升级与降级:根据锁的竞争情况动态调整锁的类型,包括: - **偏向锁**:默认情况下,当一个线程首次访问被Synchronized修饰的方法或代码块时,会尝试获取偏向锁。如果该对象之前从未被任何线程访问过,则通过CAS操作设置线程ID在对象头部的MarkWord字段中,表明该对象偏向于当前线程。 - **轻量级锁**:当多个线程试图获取同一个偏向锁保护的对象时,偏向锁会升级为轻量级锁。轻量级锁使用CAS操作尝试获取锁。 - **重量级锁**:当轻量级锁竞争失败时,就会升级为重量级锁,此时会真正地利用操作系统的互斥锁机制。 - **非公平锁**: - Synchronized默认是非公平锁。这意味着即便线程已经在等待队列中排队,当锁被释放时,也不一定按照排队顺序来获取锁。这种行为可能会导致某些线程长期处于等待状态,但在大多数情况下,这种方式可以减少锁的获取延迟,提高性能。 Synchronized关键字是Java并发编程中的一个重要组成部分,通过对其实现机制的理解以及JVM对其优化策略的掌握,可以更有效地在多线程环境中使用Synchronized来保证数据的一致性和安全性。
剩余23页未读,继续阅读
- 粉丝: 2617
- 资源: 264
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助