本章我们主要学习volatile轻量级锁、synchronized关键字及原子操作的原理。
volatile的应用
概念:volatile是一种轻量级的synchronized(锁)。
特点:
- 保证可见性
- 不保证原子性
- 禁止指令重排
1 | /** |
1 | /** |
synchronized的实现原理与应用
概念:锁
三种表现形式:
- 对于普通同步方法,锁是当前实例对象。
- 对于静态同步方法,锁是当前类的Class对象。
- 对于同步方法块,锁是Synchonized括号里配置的对象。
Java对象头
synchronized用的锁是存在Java对象头里的。
锁的升级与对比
Java SE 1.6为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”,在
Java SE 1.6中,锁一共有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状
态和重量级锁状态,这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级,意味着偏
向锁升级成轻量级锁后不能降级成偏向锁。
原子操作的实现原理
概念
原子:不能被进一步分割的最小粒子。
原子操作:不可被中断的一个或一系列操作。
Java如何实现原子操作
使用循环CAS实现原子操作
- 存在几个问题
- ABA问题
- 循环时间长开销大
- 只能保证一个共享变量的原子操作
[代码] 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21/**
* @desc CAS保证原子性
* T1 100 -> 101
* T2 100 -> 2019
* @Author xw
* @Date 2019/8/20
*/
public class CasDemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(100);
// T1 100 -> 101
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t updated: " + atomicInteger.compareAndSet(100, 101) + ",value: " + atomicInteger.get());
}, "T1").start();
// T2 100 -> 2019
new Thread(() -> {
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName() + "\t updated: " + atomicInteger.compareAndSet(100, 2019) + ",value: " + atomicInteger.get());
}, "T2").start();
}
}
使用锁机制实现原子操作
锁机制保证了只有获得锁的线程才能够操作锁定的内存区域。
1 | static AtomicReference<Integer> atomicReference = new AtomicReference<>(100); |