网站代码优化方法,漂亮的网页,笑傲网站建设,专业的高密网站建设1.什么是自旋 自旋#xff08;Spinning#xff09;是一种在多线程环境下等待锁的技术。当一个线程尝试获取某个已被其他线程持有的锁时#xff0c;该线程不会立即进入阻塞状态#xff0c;而是会在一个循环中持续检查锁的状态#xff0c;即“自旋”。如果在这个过程中锁被释…1.什么是自旋 自旋Spinning是一种在多线程环境下等待锁的技术。当一个线程尝试获取某个已被其他线程持有的锁时该线程不会立即进入阻塞状态而是会在一个循环中持续检查锁的状态即“自旋”。如果在这个过程中锁被释放了那么该线程就可以立即获取锁从而避免了线程阻塞和上下文切换的开销。
2.锁升级过程的第一次自旋 第一次自旋发生在synchronized获取轻量级锁时即当一个线程尝试获取一个被其他线程持有的轻量级锁时它会自旋等待锁的持有者释放锁。 在OpenJDK8中轻量级锁的自旋默认是开启的最多自旋15次每次自旋的时间逐渐延长。如果15次自旋后仍然没有获取到锁就会升级为重量级锁。
3.锁升级过程中的第二次自旋 第二次自旋发生在synchronized 轻量级锁升级到重量级锁的过程中。即当一个线程尝试获取一个被其他线程持有的重量级锁时它会自旋等待锁的持有者释放锁。 在OpenJDK8中默认情况下不会开启重量级锁自旋。如果线程在尝试获取重量级锁时发现该锁已经被其他线程占用那么线程会直接阻塞等待锁被释放。如果锁被持有时间很短可以考虑开启重量级锁自旋避免线程挂起和恢复带来的性能损失。
4.自适应自旋 在JDK6中之后的版本中JVM引入了自适应的自旋机制。该机制通过监控轻量级锁自旋等待的情况动态调整自旋等待的时间。 如果自旋等待的时间很短说明锁的竞争不激烈当前线程可以自旋等待一段时间避免线程挂起和恢复带来的性能损失。如果自旋等待的时间较长说明锁的竞争比较激烈当前线程应该及时释放CPU资源让其他线程有机会执行。 自适应的自旋实现在ObjectSynchronizerFastHashCode(函数中。该函数会根据轻量级锁自旋等待的情况调整自旋等待的时间。
5.自旋的实现
在OpenJDK 8的源码中synchronized的升级过程中涉及到了多次自旋操作其中包括: 第一次自旋在尝试获取轻量级锁失败后线程会进行自旋使用CAS操作去尝试获取锁。这里的 自旋并没有使用while循环而是使用了C的inline函数如ObjectSynchronizer:FastLock0)。 第二次自旋在尝试获取重量级锁失败后线程会进行自旋等待拥有锁的线程释放锁。这里的自 旋同样使用了C的inline函数如ObjectSynchronizer…FastUnlock()。 自适应自旋在尝试获取轻量级锁时线程会进行自旋等待拥有锁的线程释放锁。但这里的自旋不是固定次数的而是根据前一次自旋的时间和成功获取锁的概率进行自适应调整。这里的自旋实现在C的Thread.inline.hpp中如Thread:SpinPause(。 需要注意的是虽然这些自旋操作并没有使用while循环实现但其本质上都是在不断尝试获取锁或等待锁的过程中循环执行的。这些循环操作使用的是各种内建函数、指令集和C的语法特性实现能够更高效地执行自旋操作从而提升锁的性能。