zoukankan      html  css  js  c++  java
  • [转]各种互斥量的总结

    研究生阶段一直使用C++,到工作时,才接触到Java。写了这么多年的多线程程序,觉得对于互斥(注意,不是同步哦)的各种锁有必要做个总结。

    这里我想将Windows,Linux和Java JVM三种环境中使用锁的环境及虽然将Windows,Linux和Java JVM放在一起比较是有些不合适的,但是对基于Windows操作系统C++,Linux操作系统C++及Java程序而言,在应用层面上来说,这种横向比较对于加深对于多线程互斥中锁应用上的理解,是有意义的。如果有不正确的地方,欢迎指正。

    Windows

    有InterLock系列函数,CRITICAL_SECTION临界区,SRWLock读写锁,Mutex互斥量

    Linux

    有atomic_t,Mutex互斥量,,rwlock读写锁

    Java JVM

    有Atomic原子操作,synchronized同步关键字,ReentrantLock,ReentrantReadWriteLock读写锁

    互斥量

    环境

    睡眠锁 / 自旋锁

    可重入 / 不可重入

    用户态 / 内核态

    可被中断 / 不可被中断

    备注

    CRITICAL_SECTION 临界区

    Windows

    先自旋锁,后睡眠锁

    可重入

    用户态

    SRWLock 读写锁

    Windows

    读写锁

    不可重入

     用户态

    Mutex 互斥量

    Windows

    睡眠锁

     不可重入

    内核态

    spin_lock

    Linux

    自旋锁

     内核

    Mutex 互斥量

    Linux

    睡眠锁

     pthread

    rwlock

    Linux

    读写锁

     pthread

    synchronized

    JVM

    类自旋锁

    可重入

    JVM 内部锁

    ReentrantLock

    JVM

    类睡眠锁

    可重入

    Java 类库的锁

    ReentrantReadWriteLock

    JVM

    读写锁

     可重入

     Java类库的锁

    这里着重说一下,何时使用自旋锁,何时使用读写锁,何时使用睡眠锁。

    在临界区范围较小,竞争不强,并且其中没有读写文件之类的内核态操作时,最好使用自旋锁;这是因为,自旋锁是以一种“忙等”的方式抢占锁,如果临界区范围较大,或竞争很强,或者有内核态操作,导致多个线程同时等待一个自旋锁资源,服务器的CPU使用率将会非常高,上下文切换会比较频繁,性能不佳。对于Windows的临界区,微软特别做了优化,它会先自旋一段时间,然后,如果长时间进入不了临界区,则会使用互斥量进入睡眠状态。

    在读写数量上差距很大时,(读多写少或者写多读少),使用读写锁;读写锁,大多数情况下都是自旋锁的一个变种。

    在临界区范围较大或者临界区其中有内核态操作时,最好使用睡眠锁;睡眠锁在抢占不到锁的情况下,会进入内核态,使自身所在的线程被挂起。在临界区较小时,进入内核态的时间长度很可能大于在临界区中的时间长度,导致性能不佳,但是如果临界区很大,其中操作时间长度大于睡眠锁进入内核态的时间长度,尤其是在竞争很强的情况下,性能相对自旋锁要好些。

    对于JVM,为什么我会写类自旋锁和类睡眠锁,这是因为,它们的性能情况和在C++下是不一样的,在Java5.0中,synchronized的性能和ReentrantLock的性能的对比与自旋锁和睡眠锁的性能对比类似,但是在Java6.0中则不然,synchronized在竞态的性能有了大幅的提高,使得在竞态情况下,synchronized的性能和ReentrantLock的性能基本一致。

    最后,也是最重要的是,以上说法都不准确,唯一准确的是在你自己的代码中测试性能的结果。

  • 相关阅读:
    Core中间件——访问记录
    前段时间蛮火的哄老婆的小玩具
    PHP word PDF excel 文档互转 预览 (linux libreoffice)
    PHP Excel Word 文件转 HTML输出
    mysql skip-name-resolve 的解释
    使用fastcgi_finish_request提高页面响应速度
    PHP SplQueue 实现队列
    mysql in条件查询到底会不会用到索引
    安装 docker-compose 配置 lnmp
    使用docker 安装 LNMP
  • 原文地址:https://www.cnblogs.com/qq78292959/p/4607332.html
Copyright © 2011-2022 走看看