Java那点琐事

作者: blueMononoke | 来源:发表于2019-05-16 18:07 被阅读0次

    Java中的锁有很多种,经常会听到“锁”这个词。

    犹如每天出门时,🔑就是一种“锁”,拿不到🔑,就进不去了。

    锁的种类

    1 悲观 Vs 乐观

    林妹妹比较悲观,宝玉比较乐观
    悲观如林妹妹,怕多行一步路,怕多说一句话,被人耻笑了去。担心外人所说,“金石良缘”,怕宝玉的心思会变。不敢多表露心思,总是猜疑,总想去证明。

    而宝玉,天性乐观一些,总觉得这个妹妹是见过的,总觉得以后就是会和这个妹妹在一起的,不需要多证明。“你证我证,心证意证。是无有证,斯可云证。无可云证,是立足境”。

    1.1 悲观锁

    看名字便知,它是悲观的,总是想到最坏的情况。
    锁也会悲观,它并不是难过,它只是很谨慎,怕做错。

    每次要读data的时候,总是觉得有“坏人”会修改数据,所以先加个🔐,让“坏人”不能改数据,再慢慢读~
    就像你每次出门用🔑锁门一样。

    应用:
    synchronized关键字和Lock的实现类都是悲观锁。

    1.2 乐观锁

    它很乐观,总是想着最好的情况。
    它比较大条,不会太担心。如果要发生,总会发生,如果不会发生,那就不会。为什么要担心那么多?

    每次读data时,总是乐观地想没有“坏人”会同时修改数据,不用加锁,放心地读data。
    但在更新的时候会判断一下在此期间别人有没有去更新这个数据。

    相信“天下无贼”。

    事事无绝对,悲观也好乐观也好,没有绝对的悲观,也没有绝对的乐观。只是在这个当时,相信,还是不相信。

    CAS(Compare and Swap 比较并交换)

    是乐观锁的一种实现方式。

    简单来说,有3个三个操作数:

    • 需要读写的内存值 V。
    • 进行比较的值 A。
    • 要写入的新值 B。

    2 公平 Vs 非公平

    没有绝对的公平,也没有绝对的不公平。

    公平,就是按顺序排队嘛。
    公平锁维护了一个队列。要获取锁的线程来了都排队。

    waitQueue.png

    非公平,上来就想抢到锁,好像一个不讲道理的,抢不到的话,只好再去乖乖排队了。
    非公平锁没有维护队列的开销,没有上下文切换的开销,可能导致不公平,但是性能比fair的好很多。看这个性能是对谁有利了。

    3 独享 Vs 共享

    好比你自己的自行车,就是你独享的资源。
    OFO、摩拜单车,就是共享的资源,但也是一次只能一个人用啦。更好的例子,比如说一条小溪,可以同时好几只小鹿在溪边喝水小溪就是共享的嘛~

    4 可重入锁

    广义上的可重入锁,而不是单指JAVA下的ReentrantLock。

    可重入锁,也叫做递归锁,指的是同一线程外层函数获得锁之后,内层递归函数仍然有获取该锁的代码,但不受影响。

    可重入锁最大的作用是避免死锁。

    • synchronized
    • ReentrantLock

    构造函数提供了是否公平锁的初始化

    /**
         * Creates an instance of {@code ReentrantLock}.
         * This is equivalent to using {@code ReentrantLock(false)}.
         */
        public ReentrantLock() {
            sync = new NonfairSync();
        }
    
        /**
         * Creates an instance of {@code ReentrantLock} with the
         * given fairness policy.
         *
         * @param fair {@code true} if this lock should use a fair ordering policy
         */
        public ReentrantLock(boolean fair) {
            sync = fair ? new FairSync() : new NonfairSync();
        }
    

    使用ReentrantLock必须在finally控制块中进行解锁操作。

    在资源竞争不激烈的情形下,性能稍微比synchronized差点点。但是当同步非常激烈的时候,synchronized的性能一下子能下降好几十倍,而ReentrantLock确还能维持常态。

    高并发量情况下使用ReentrantLock。

    • Semaphore
    • AtomicInteger、AtomicLong等

    参考:

    1. 关于Java锁机制面试官会怎么问,深刻易懂 https://mp.weixin.qq.com/s/NG_xGcEHsxOJbgBgHRTK4Q
    2. 不可不说的Java“锁”事
      https://mp.weixin.qq.com/s/E2fOUHOabm10k_EVugX08g

    相关文章

      网友评论

        本文标题:Java那点琐事

        本文链接:https://www.haomeiwen.com/subject/dvnavqtx.html