资讯专栏INFORMATION COLUMN

java重入锁、公平锁和非公平锁

netmou / 1326人阅读

摘要:很吧判断是否有前驱线程等待获取锁公平所和非公平锁的各自优势是什么那公平锁很好理解,可以防止出现线程饥饿现象,每一个线程都有机会获取到锁。非公平锁可能会导致线程饥饿,但是我们一般使用非公平锁,因为非公平锁可以减少上下文的切换,提高效率。

锁的重入是指同一个线程可以多次获取同一个锁,synchronize是隐式的可重入锁,ReentrantLock通过代码实现了锁的重入:
    final boolean nofairTryAcquire(int acquires){
        final Thread current=Thread.currentThread();
        int c=getState();
        if(c==0){
              if(compareAndSetState(0,acquires)){
                  setExclusiveOwnerThread(current);
                  return true;
              }
        }else if(current==getExclusiveOwnerThread()){
            int nextc=c+acquires;
            if(nextc<0) throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;
    }

从上面的代码中,可以一目了然的发现,当获取锁的线程与拥有锁的线程是同一个线程时,仅会对状态进行累加。so easy ,并没有什么难度。那接下来我们想一下,如何实现公平所和非公平锁,上面的代码是非公平锁的实现方式。那如何实现公平锁那?所谓的公平锁就是所有获取锁的线程都要按照“先来后到”的顺序获取锁。假设线程B在阻塞队列中,等待获取锁,如果还有一个线程A在B的前面,那么B就要让A先获取锁。因此在B尝试获取锁之前,只要判断一下它是否还有前驱的队列即可。很easy吧:

final boolean fairTryAcquire(int acquires){
        final Thread current=Thread.currentThread();
        int c=getState();
        if(c==0){
              if(!hasQueuedPredecessors()&&compareAndSetState(0,acquires)){//判断是否有前驱线程等待获取锁
                  setExclusiveOwnerThread(current);
                  return true;
              }
        }else if(current==getExclusiveOwnerThread()){
            int nextc=c+acquires;
            if(nextc<0) throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;
    }

公平所和非公平锁的各自优势是什么那?公平锁很好理解,可以防止出现线程饥饿现象,每一个线程都有机会获取到锁。非公平锁可能会导致线程饥饿,但是我们一般使用非公平锁,因为非公平锁可以减少上下文的切换,提高效率。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72822.html

相关文章

  • Java ReentrantLock 原理分析

    摘要:的主要功能和关键字一致,均是用于多线程的同步。而仅支持通过查询当前线程是否持有锁。由于和使用的是同一把可重入锁,所以线程可以进入方法,并再次获得锁,而不会被阻塞住。公平与非公平公平与非公平指的是线程获取锁的方式。 1.简介 可重入锁ReentrantLock自 JDK 1.5 被引入,功能上与synchronized关键字类似。所谓的可重入是指,线程可对同一把锁进行重复加锁,而不会被阻...

    lx1036 评论0 收藏0
  • J.U.C|可ReentrantLock

    摘要:二什么是重入锁可重入锁,顾名思义,支持重新进入的锁,其表示该锁能支持一个线程对资源的重复加锁。将由最近成功获得锁,并且还没有释放该锁的线程所拥有。可以使用和方法来检查此情况是否发生。 一、写在前面 前几篇我们具体的聊了AQS原理以及底层源码的实现,具体参见 《J.U.C|一文搞懂AQS》《J.U.C|同步队列(CLH)》《J.U.C|AQS独占式源码分析》《J.U.C|AQS共享式源...

    wangdai 评论0 收藏0
  • 不可不说的Java”事

    摘要:本文旨在对锁相关源码本文中的源码来自使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景。中,关键字和的实现类都是悲观锁。自适应意味着自旋的时间次数不再固定,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。 前言 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8)、使用场景...

    galaxy_robot 评论0 收藏0
  • Java并发编程,深入理解ReentrantLock

    摘要:公平锁为了保证时间上的绝对顺序,需要频繁的上下文切换,而非公平锁会降低一定的上下文切换,降低性能开销。因此,默认选择的是非公平锁,则是为了减少一部分上下文切换,保证了系统更大的吞吐量。ReentrantLock简介ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁, 支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻...

    番茄西红柿 评论0 收藏0
  • Java并发编程,深入理解ReentrantLock

    摘要:公平锁为了保证时间上的绝对顺序,需要频繁的上下文切换,而非公平锁会降低一定的上下文切换,降低性能开销。因此,默认选择的是非公平锁,则是为了减少一部分上下文切换,保证了系统更大的吞吐量。ReentrantLock简介ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁, 支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻...

    番茄西红柿 评论0 收藏0

发表评论

0条评论

netmou

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<