final 关键字标识的变量,我们知道,final 变量存在于常量池中,定义即需要初始化,且具有不可变性。所以并发中对于其的使用时线程安全的。
final 可以修饰变量,方法及类对象。
不可变:不可被修改,不可被集成,不可被覆盖,重写等。
锁的本质就是一个同步块,处于同步块儿中的操作可以认为是线程安全的。
那怎么加锁呢?
1、synchronized 关键字:
底层其实对应的是用monitorenter及monitorexit字节码指令包裹需要同步的执行。
monitorenter
... ...
monitorexit
同一个线程对同一个同步块的加锁,只会执行一次,当获取到锁后,再次进入同步块时,则不需要再次进行加锁,我们称之为“可重入”,当然,重入也会被记录,
线程对对象的加锁标识,存在于对象的头信息中,具体可以了解下:偏向锁、轻量锁、重量所,锁膨胀相关知识。
对于静态执行的锁:锁类对象。
对于费静态执行的锁:锁类实例。
2、lock:
我们称之为可重入锁。
可重入,也就是我们上面所说的,在获锁期间,可以重复进入。
相对于synchronized来说,lock更加灵活:可中断,可超时,公平锁等。
lock的实现基于AQS。
基本使用:
try {
lock();
... ...
} finally {
unlock();
}
特别需要注意的一点是一定要保证unlock。
局部变量,其实实操对应的是线程私有栈中的变量操作。因为私有,所以是线程安全的。
线程栈具体参考:Java虚拟机栈
局部变量以栈帧的形态参与实际的运行计算。
CAS自旋
轻量锁
偏向锁
锁粗化
避免不必要的锁
等等。
原文:https://www.cnblogs.com/niejunlei/p/12863360.html