JVM 锁分类

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ocp114/article/details/82812374

首先对象的锁是怎么实现的?在这里就需要先了解一下 在对象头(Object Header)里面的 Mark Word(标记字段),听说这个东东在 32位 JVM 中占 32bit,64位JVM 中占 64bit,相当小;用于存储对象的 hashCode、垃圾回收标记、年龄、锁信息等,所以这里粗略的可以认为锁大概就是在 Mark Word 上的一个标记了,好,入正题:

偏向锁

  1. -XX:+UseBiasedLocking:启用偏向锁
  2. -XX:-UseBiasedLocking:禁用偏向锁(一般只有在高度并发的情况下才有明显的优化效果)
  3. -XX:BiasedLockingStartupDelay=0:系统启动后马上启用偏向锁(由于系统启动或 JVM 默认并非马上启用的)
  4. 下面是测试代码,在固定 -Xmx2048m -Xms2048m 的情况下,我这边经过几次的测试,测到的是启用后,性能会下降 5% 左右,看来还是挺有用的
public class TestBiasedLock {
	// Vector 内是有锁的
	public static List<Integer> numberList = new Vector<Integer>();
	public static void main(String[] args) {
		long begin = System.currentTimeMillis();
		
		int num = 0;
		int count = 0;
		while(count < 50000000) {
			numberList.add(num);
			num += 2;
			count++;
		}
		
		long end = System.currentTimeMillis();
		System.out.println(end - begin);
	}
	
}

轻量级锁(BasicObjectLock)

  1. 是嵌入在 Java 栈中的对象
  2. 当前线程申请偏向锁失败时会去申请 BasicObjectLock 对象
    在这里插入图片描述
  3. 当前一个对象被加锁时,整个 Mark Word 变成指向 BasicLock 对象的指针,当锁释放时,BasicLock 会把 markOop _displaced_header 还原回去给对象
  4. 在高并发时轻量级锁会产生线程不断去申请锁的情况,导致性能下降

自旋锁

  1. 在并发量较高,线程存在资源竞争的时候,让线程做几个无用功,相当于在原地逛几圈,从而等待获取锁
  2. 这样的做法减少了系统层面的线程挂起,从而提高性能,但是如果长时间获取不到锁,同样会出问题,有可能最终还是会被挂起,降低系统性能

以上就是 JVM 层面的锁,基本上都是从 偏向锁 开始申请,如果申请不到再变成 轻量级锁 再到 自旋锁 最后还不行就是使用 OS 互斥量 在操作系统层挂起,这里值得注意的是,说了这么多,到底我在说啥?简单理解,锁!就是把一块或几块内存空间圈起来不让其他线程读或写,这里加锁的不是对象哦,是对象的实例所在的内存空间,就这样~~

对于锁的优化

  1. 减少锁的持有时间:对于部分不必要加锁的代码就不用加锁了
    减少锁的持有时间
  2. 减小锁的粒度:将大对象拆分成小对象,加锁时,就变成了,锁住大对象的某一部分,而不是一整个大对象,使得锁住的代码块或者对象范围缩小,例如 HashMap 和 CurrentHashMap 的区别
  3. 锁分离:典型的就是读写分离了,对于对象的读和写分别使用不同的锁 例如 mybatis 二级缓存的 ReadWriteLock,读时可以多线程,写时只能单个线程,对于读多写少的场景有很大的帮助
  4. 锁粗化:顾名思义,其实就是粒度增大加锁范围
    在这里插入图片描述
  5. 锁消除:这个是 JVM 自动判断的,如果某些不可能发生线程共享情况的变量被加锁了, JVM 或自动把该锁去掉,从而提高性能
  6. 无锁:
    • 采用 CAS (Compare And Swap)操作
    • 是一种非阻塞同步的方式
    • 从应用层面判断多线程的干扰,效率更高
    • 实现的原理是 CAS(V, E, N) ,当且紧当 E = V 时,N 才更新到 V 中,这里的 V 是变量名,E 是期望值,N 是要更新到 V 的值
    • java.util.concurrent.atomic 包下的 class 都是用这种方式实现的

猜你喜欢

转载自blog.csdn.net/ocp114/article/details/82812374