Java中的关键字synchronized 详解
Java中的关键字synchronized 详解 Java中的关键字synchronized是Java语言中用于线程同步的关键字。它可以修饰方法或代码块,以便在多线程环境中保护共享资源的安全。 1、修饰普通方法 synchronized关键字可以修饰普通方法,以便保护方法内的资源。例如: ```java private synchronized void synMethod() { // 方法体 } ``` 在这种情况下,synchronized锁的对象实例。 2、修饰静态方法 synchronized关键字也可以修饰静态方法,以便保护类中的静态资源。例如: ```java private static synchronized void synMethod() { // 方法体 } ``` 在这种情况下,synchronized锁的是当前Class类对象。 3、同步方法块 synchronized关键字还可以用于修饰代码块,以便保护特定的资源。例如: ```java private void synMethod1() { synchronized (this) { // 方法体 } } ``` 在这种情况下,synchronized锁对象实例。 ```java private void synMethod2() { synchronized (ThreadTest.class) { // 方法体 } } ``` 在这种情况下,synchronized锁的是当前Class类对象。 锁原理 在了解锁原理之前,先认识一下Java对象头Mark Word。Mark Word是对象头中的一个32位的字段,用于存储对象的锁状态信息。 | 锁状态 | 25 bit | 4 bit | 1 bit | 2 bit | | --- | --- | --- | --- | --- | | 无锁 | 对象hashCode | 对象分代年龄 | 01 | 00 | | 偏向锁 | 线程ID | Epoch | 01 | 01 | | 轻量锁 | 指向栈中锁记录的指针 | 00 | 00 | | 重量锁 | 指向互斥量的指针 | 10 | 10 | | GC标记 | GC标记 | 11 | 11 | 锁原理可以分为三种:偏向锁、轻量锁和重量锁。 偏向锁 偏向锁是Java 6中引入的一种锁机制,它的目的是为了减少无竞争的情况下的锁开销。在这种情况下,线程在访问同步块时,如果没有其他线程对锁进行竞争,并且由同一个线程多次获得锁,也就是单线程运行同步代码,在这种情况下,若是每次还阻塞线程,就代表白白浪费CPU性能。这种情况下,引入了偏向锁概念。 偏向锁的工作流程: 1. 访问同步代码块 2. 判断对象头Mark Word中存储的线程ID是否指向当前线程,如果是,则表明当前是锁的重入,不需要再获得锁,直接执行同步代码 3. 如果不是,则尝试使用CAS算法将线程ID更新至对象头中。 4. 成功,获得锁,执行同步代码。更新失败表明存在锁竞争,等待全局安全点,暂停拥有偏向锁的线程,根据对象头的锁标志位,选择将偏向锁升级为轻量锁或者置为无锁。 轻量锁 轻量锁是Java 6中引入的一种锁机制,它的目的是为了减少竞争的情况下的锁开销。在这种情况下,线程在访问同步块时,先在当前线程的线程栈中创建一个锁记录(Lock Record)区域。把对象头Mark Word拷贝到Lock Record中。利用CAS尝试将对象头Mark Word中的线程指针更新为指向当前线程的指针更新成功,则获得轻量锁。更新失败,检查Mark Word中的指针是否指向当前线程。如果是,则说明是锁的重入现象。执行同步代码块如果不是,则说明此时存在竞争。需要把轻量锁膨胀为重量锁。 重量锁 重量锁是基于对象监视器(Monitor)来实现的。线程在执行同步代码时,需要调用一个Monitor.enter指令。执行退出后,调用Monitor.exit指令。这里看得出,监视器具有排它性,一个时间点只能有一个线程enter成功,其他线程只能阻塞在队列中。所以这种重量锁的操作成本很高。 synchronized关键字是Java语言中用于线程同步的关键字,它可以修饰方法或代码块,以便保护共享资源的安全。但是,synchronized关键字也存在一定的开销,因此在实际应用中需要根据具体情况选择合适的锁机制。
- 粉丝: 4
- 资源: 914
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助