java基础(十一)操作系统中锁机制

前言:前几天阿里电面被问到了关于jvm锁机制的底层原理,说实话当时只是简单的了解基础api,真正内部实现确实不懂。所以在查阅大量资源的情况下,简单记录下我学习这方面的资料。

一.操作系统级别的锁机制实现原理
我们知道jvm是属于运行在操作系统上的程序虚拟机。要想真正理解jvm是如何实现锁机制的,底层操作系统的锁机制是必须要了解的。
我们知道在多线程编程中,为了保证数据操作的一致性,操作系统引入了锁机制,用于保证临界区资源的安全。通过锁机制,能够保证在多核多线程环境中,在某一个时间点上,只能有一个线程进入临界区,从而保证临界区中操作数据的一致性。

锁可以理解为内存中的一个变量标识,拥有两种状态:unlock,locked.任何想要访问获得锁的线程必须执行以下指令流


load lock #将lock内存值加载进cpu
read lock state
if lock.state=="unlock"
set lock.state to "locked" #将lock状态设置会内存
return true
return false


我们假设2个线程同时想获得锁,当线程一执行完第二条指令之后,突然被中断。那么cpu去执行线程二的指令流,假设线程二成功执行以上指令并获得锁。这时cpu再切换回线程一继续执行,那么这时,线程一操作的lock是已经缓存在寄存器中的lock,该lock状态为free,所以也去获得这把锁,这也就意味着这2个线程可以同时去操作临界资源,这也就意味着该机制是没有起作用的。

1.中断机制

如果我们能将以上多个指令流变成一个不可中断的原子操作,问题不就解决了?所以我们在执行执行这些指令时,可以通过开关中断来保证锁机制指令流的原子性。中断是系统级别的指令,最好不允许用户操作,如果代码中没有正确的开关中断,容易引发系统死机。

2.CAS机制

CAS是Compare And Set的一个简称。
对于一个线程来说,从内存load线程上下文到处理器的高速缓存,这里的线程上下文包括共享变量;然后执行线程代码,这里包括共享变量的读操作和写操作,因为写操作会导致多个处理器处理的数据不一致,所以CAS上场了,它要求写操作的时候,检查要写的共享变量cache和内存是否一致,若一致则继续执行写操作,若不一致则重新load线程上下文,重新执行。

这里写图片描述

但是这一个过程实际上是分为两步:比较(compare)和写回(swap).所以可能存在临界点,需要硬件锁来保障原子性,一种典型的方法就是总线锁,在处理器连接的总线上发出一个Lock信号,阻塞其他处理器操作内存。

这里写图片描述

我们通过源码可以看到AtomicInteger类compareAndSet通过原子操作实现了CAS操作。

CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

private volatile int value;//保证可见性
public final int get() {
        return value;
   }
public final int incrementAndGet() {
  for (;;) {
        //获取当前值
        int current = get();
        //设置期望值
        int next = current + 1;
//调用Native方法compareAndSet,执行CAS操作
   if (compareAndSet(current, next))
 //成功才返回值,否则重复执行循环(自旋)
       return next;
      }
}

value是一个volatile变量,不同线程对这个变量进行操作时具有可见性,修改与写入操作都会存入主存中,并通知其他cpu中该变量缓存行无效,保证了每次读取都是最新的值。

但是该CAS也存在一些问题,但是会导致一个ABA。如线程一和线程二都取出了主存中的数据为A,这时候线程二将数据修改为B,然后又修改为A,此时线程一再次去进行compareAndSet的时候仍然能够匹配成功,而实际对的数据已经发生了变更了,只不过发生了2次变化将对应的值修改为原始的数据了,并不代表实际数据没有发生变化。这个可以通过引入对应修改的版本号来确定修改的操作。

3.内存锁机制
以上是在单核cpu下执行没有问题,但是在多核cpu下呢?开关中断是针对当前cpu,所以也没法保证原子性。我们主要到以上锁机制是需要读写内存操作的。如果我们将只运行一个线程同时操作内存,那不就行了。我们就想到cpu与内存进行通信的总线。即我们锁住总线即可。

在硬件层面,CPU提供了原子操作、关中断、锁内存总线的机制;其他所有的同步机制都是基于这些基本的锁机制。经过以上内容的介绍,相信对操作系统中锁机制有了全新认识。

4.三种机制总结
1) 中断机制其实是一种悲观锁(只允许一个进程操作临界资源,其他进程处于阻塞状态
2)CAS是一种乐观锁,即先不要担心其他线程会修改共享变量,在适当的时候检查其他线程是否已经修改共享变量,如果未修改则说明可以进行操作。CAS一般适用于计数;多线程编程也适用。
3)内存锁机制是应用非常多的,比如上述CAS机制部分也是利用了内存锁机制

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值