zoukankan      html  css  js  c++  java
  • 乐观锁和悲观锁

    1 基本概念

    悲观锁就是说,如果共享资源被别的线程占用了,那么其它所有的线程都得sleep等待。

    乐观锁是说,弄一个死循环,假如共享资源被别的线程占用了,那么我就再试,死也不等待。

    2 实现案例之一

    java的AtomicInteger的

    incrementAndGet()

    实现的原理:

    public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }

    其中compareAndSet由处理器提供的原子指令CMPXCHG来实现,如果这是一个单核的cpu,那么就不需要锁了,因为自带锁属性,但是如果是一个多核的cpu,那么该指令就会锁住内存,然后完成比较,如果相同,那么更新内存中的值,如果不同,那么放弃。

    总体的思路是这样的。我死也不sleep等待,我不听的尝试,每次的尝试的步骤是这样的:我先获取内存中的值(多核cpu,每次只允许一个核访问同一内存,这个是硬件上保证的),然后加1,这个时候我想要更新内存了,但是,我调用CMPXCHG来进行更新,看看内存中的值是不是已经被别人更新了,如果老值等于现在的值就说明没有被更新,所以我可以更新,否则,放弃本次尝试,继续下一次的尝试。

    3 数据库中的乐观锁的原理是一样的

    使用乐观锁的表有一个version字段,读取数据时,该字段会被一起读出,更新数据时,将其加1,提交数据前先比较当前数据库中的版本号和新的version,如果新的version大于当前数据库的版本号就说明之前读取的数据没有过期,可以写入。这里查看当前数据库中表的版本号、比较版本号和写入数据的操作是需要加悲观锁的。只不过任何人读数据库不用加悲观锁。

  • 相关阅读:
    TCP /IP协议的理解
    Linux 文件大小跟踪命令
    关于3D旋转的本质
    Unity旋转
    QT解析XML(机械拆装)
    红黑树总结
    EXCEPTIONS
    算数运算符注意事项
    java中常用的转义字符
    常量和数据类型
  • 原文地址:https://www.cnblogs.com/hustdc/p/8422391.html
Copyright © 2011-2022 走看看