java并发编程艺术笔记-重入锁

ReentrantLock-重入锁
该锁支持一个线程对资源的重复加锁,还支持公平锁,和非公平锁
公平锁表示等待以及优先级高的线程会获得锁,非公平锁谁抢到就是谁的

锁的计算,当前线程获得锁或者再次获得锁,则state+1,反之-1 ,0代表线程已经释放了锁
获取锁(默认是非公平获取锁):

final boolean nonfairTryAcquire(int acquire){
  //得到当前线程
  final Thread current = Thread.currentThread();
 //拿到当前资源的状态
  int c = getStatea();
//0代表被当前资源已经被释放了锁,可以获得锁
  if(c = 0 ){
    //当前线程获得锁,返回true
    if(compareAndSetState(0,acquire){
      setExclusiveOwnerThread(current);
      return true;
    }
   }else if(current = getExclusiveOwnerThread()){
      //当前线程继续获得锁,state+1
      int nextc = c+acquires
      if(nextx < 0)
        ....
      //设置当前资源锁的最新state
      setState(nextx);
      return ture;
  }

return false;
}

在释放锁的时候要state-1

protected final boolean tryRelease(int release){
  //当前资源状态--
  int c = getState() - release;
  if(Thread.currentThread()!=getEx....()){
    throw ...
   }
  boolean free = false;
  //==0代表线程已经释放该资源的锁
  if(c ==0){
   free == true;
    setEx...(null);
  }
  setState(c)
  return free;
}

公平获得锁:
和非公平获得锁有一点差别就是要判断当前线程的队列是否前面还有线程,就是是否还有前驱节点,方法为hasQueuedPredecessors(),如果返回true则代表前面还有节点,说明自己不能获得锁,和上述的代码区别只有一处不同:

...
if(c==0){
   //判断是否为队列的第一个,公平的竞争获得锁
  if(!hasQueuedPredecessors() && compareAndSetState(0,acquires){
  ...
  }
}
...

那么为什么非公平锁是默认的呢?
在书中给出的例子中,非公平锁的开销比较少,应为相同线程再次获得锁快呀。。。

到这里会问,为什么要发明重入锁这么个东西,在平常的场景中会有这样的情况,当前线程访问一个加锁的方法时候,这个线程又在执行另一个方法也要走这个加锁的方法,如果不是重入锁,那么就会变成了死锁(当前线程的走的第一个方法一直持有锁,第二个方法始终等待锁,方法1可能会等待方法2的返回值,但是方法2一直等待方法1的释放锁,这样就成了死锁)。。。有了重入锁,就避免了这样的问题。

你可能感兴趣的:(java并发编程艺术笔记-重入锁)