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

锁的重入是指同一个线程能够屡次获取同一个锁,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吧:ui

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;
    }

公平所和非公平锁的各自优点是什么那?公平锁很好理解,能够防止出现线程饥饿现象,每个线程都有机会获取到锁。非公平锁可能会致使线程饥饿,可是咱们通常使用非公平锁,由于非公平锁能够减小上下文的切换,提升效率。线程

相关文章
相关标签/搜索