JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)

JVM虚拟机规范学习笔记

ThreadLocal

当一个变量想要多线程共享时我们可以用volatile修饰,当一个变量我们只想让所拥有的线程自己访问时,可以将其存入到ThreadLocal里面。通过get和set的方法进行存取。

每个Thread都有一个ThreadLocalMap对象,这个对象里面以threadLocalhashCode为k,要存储的变量为v存储。而ThreadLocal对象实例就是我们访问它的入口。

线程安全的实现方案:

1、互斥同步

他是常见的一种并发正确性保障手段。同步是指多个线程并发访问共享数据时,保证共享数据在同一个时刻只被线程使用。互斥是实现同步的一种手段。临界区、互斥量、信号量都是主要的互斥实现方式。

即我们想要同步的目的,我们可以使用互斥来实现(互斥是方法,同步是目的)。

Synchronized

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第1张图片

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第2张图片

ReentrantLock

它增加了一些高级功能:等待可中断、可实现公平锁、以及锁可以绑定多个条件。

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第3张图片

2、非阻塞同步

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第4张图片

3、无同步方案

要保证线程安全,并不是一定就要进行同步,两者没有因果关系。同步只是保证共享数据争用时的正确手段,如果一个方法本身就不涉及共享数据,那它自然就无须任何同步操作去保证正确性。

1、可重入代码

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第5张图片

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第6张图片

2、线程本地存储

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第7张图片

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第8张图片

锁优化

自旋锁和自适应自旋

根据前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定,例如一个门锁用许多钥匙都能打开,我上次去开锁一下子就打开了,那么我这次去开锁的时候,即使看到别人已经占用了锁,打开了,但是我还是会等待一段时间,尝试去开锁。而另外一个门锁,是密码锁,只有几个人知道密码,上次我去开锁的时候就失败了,我知道自己有很大的概率打不开,就不去尝试开这个锁。

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第9张图片

锁消除

判断依据主要来源于逃逸分析的数据支持。例如String的concatString方法。在jdk1.5后使用StringBuffer的append的方法进行动态拼接。因为StringBuffer对象只能在这个concatString方法里面使用,不会逃逸到其他地方,就会把StringBuffer的锁给消除掉。

image-20220218113753789

image-20220218113803529

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第10张图片

image-20220218114154635

锁粗化

还是上面的String的concatString方法中的StringBuffer的连续append,当虚拟机检测到一串零碎的操作都对同一个对象加锁,将会把加锁同步的范围扩展到整个操作序列的外部,就是扩展到第一个append()操作之前直至最后一个append()操作之后,就只需要加一次锁就可以了。

步的范围扩展到整个操作序列的外部,就是扩展到第一个append()操作之前直至最后一个append()操作之后,就只需要加一次锁就可以了。

JVM虚拟机规范学习笔记(线程安全实现方案、锁优化)_第11张图片

你可能感兴趣的:(记录,学习,安全,java)