美文网首页
Java多线程之乐观锁与悲观锁;公平锁与非公平锁

Java多线程之乐观锁与悲观锁;公平锁与非公平锁

作者: 魂之挽歌w | 来源:发表于2019-09-28 22:42 被阅读0次

    乐观锁与悲观锁;公平锁与非公平锁

    首先来讲讲乐观锁与悲观锁;公平/非公平锁的概念,这两种锁的概念其实是两个维度的,乐观/悲观锁是针对多线程之间数据共享维度的;而公平/非公平锁是多线程执行顺序维度的,一般乐观/悲观锁开发中接触地多一些,下面详细讲一讲:

    乐观锁与悲观锁

    • 悲观锁(Pessimistic Lock):顾名思义,就是在操作共享数据时,是基于其他线程一定会对该数据进行修改的假设上的,所以一定会阻塞其他线程来保证线程安全。
      举例:我们常使用的Synchronized做多线程同步就是悲观锁,具有排他性,缺点就是会容易产生死锁。
    • 乐观锁(Optimistic Lock): 与悲观锁相反,但又不是完全想法,乐观锁在读取数据时假设别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制,即对数据做版本控制。所以乐观锁适用于多读的应用类型,这样可以提高吞吐量。
      举例:CAS机制(compare and swap),简单来说会有三个操作数,当前内存变量值V,变量预期值A,即将更新值B,当需要更新变量的时候,会直接将变量值V和预期值A进行比较,如果相同,则直接更新为B;如果不相同,则当前变量值V刷新到预期值中,然后重新尝试比较更新。

    公平锁与非公平锁

    • 公平锁(Fair):加锁前检查是否有排队等待的线程,按照线程加锁的顺序来分配锁的使用权,先来先得。
    • 非公平锁(Nonfair):线程加锁时直接尝试获取锁,获取不到就自动到队尾等待。简单来说就是是一种获取锁的抢占机制,是随机获得的锁的。
      ReentrantLock锁内部提供了公平锁与分公平锁内部类之分,默认是非公平锁,如下:
    //创建一个非公平锁,默认是非公平锁
    
    Lock nonFairLock= new ReentrantLock();
    
    Lock nonFairLock= new ReentrantLock(false);
    
    //创建一个公平锁,构造传参true
    
    Lock fairLock= new ReentrantLock(true);
    

    适用场景:

      实际工作中,我们更多的是直接使用非公平锁:非公平锁比公平锁性能高5-10倍,因为公平锁需要在多核情况下维护一个队列,如果当前线程不是队列的第一个无法获取锁,增加了线程切换次数。

    参考

    相关文章

      网友评论

          本文标题:Java多线程之乐观锁与悲观锁;公平锁与非公平锁

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