JUC 之 ReetrantLock

lock()

//获取锁,一直等待锁可用
 public void lock() 
 {
        sync.lock();
 }
 //公平锁获取
 final void lock() 
 {
            acquire(1);
 }
 //非公平锁的获取
  final void lock() 
  {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
  }

FairSync.tryAcquire

Function execution process:
(1) If the current lock state stateis 0, indicating that the lock is in the idle state can be acquired. First call hasQueuedPredecessors determine whether the current node in the precursor thread there waiting to acquire the lock. If there are no direct return false; not the case, by calling compareAndSetState (CAS) to modify the value of state to mark that they have to get the lock, call the CAS after the successful implementation of setExclusiveOwnerThread set the lock holder for the current thread. Now the program execution to illustrate lock acquisition succeeds, the return to true;
(2) if the current state of the lock state is not zero, but the current thread already holds the lock (current == getExclusiveOwnerThread ()), because the lock is reentrant (multiple acquisitions ), updating the lock state after the re-entry state + = acquires. Returns true if successful lock acquisition.

 protected final boolean tryAcquire(int acquires) 
 {
            final Thread current = Thread.currentThread();
            //获取锁状态
            int c = getState();
            if (c == 0) 
            {
                if (!hasQueuedPredecessors() &&   //判断当前线程是否还有前节点
                    compareAndSetState(0, acquires)) //CAS方法修改state
                    {
                    		//获取锁成功,设置锁的持有线程为当前线程
		                    setExclusiveOwnerThread(current);
        		            return true;
                }
            }
            // 已经持有锁
            else if (current == getExclusiveOwnerThread()) 
            {
               //重入
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                //更新state的状态
                setState(nextc);
                return true;
            }
            return false;
 }

NonFairSync.tryAcquire

 protected final boolean tryAcquire(int acquires) 
 {
            return nonfairTryAcquire(acquires);
 }
 
 final boolean nonfairTryAcquire(int acquires) 
 {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) 
            {
                if (compareAndSetState(0, acquires))  //CAS修改state
                {
                    setExclusiveOwnerThread(current);
                	    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) 
            {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
 }

Note: the lock can be seen by comparing the fair and unfair tryAcquire lock code, unfair lock acquisition omitted hasQueuedPredecessors () this operation, which means it does not determine whether the current thread there before node (prev node! ) get locked in wait, but directly to carry out lock acquisition operation.

unlock

//释放锁
public void unlock() 
{
    sync.release(1);
}

tryRelease

        protected final boolean tryRelease(int releases) 
        {
            // 计算释放后的state的值
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) 
            {
                //锁全部释放,可以唤醒下一个等待线程
                free = true;
                //设置锁持有线程为null
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

Note: tryRelease for the release of a given amount of resources. In ReetrantLock in each release is 1, that is, the number of reentrant lock, gets the lock must be equal to the number of times to release the lock, this is the real release the lock. Under can wake up in the (state == 0) all lock release a waiting thread.

Wait condition Condition

Condition Condition interface and the interface to achieve AQS

synchronized and ReentrantLock choice

Same semantics as built-in locks synchronized ReentrantLock provided on the lock and memory, It also provides a number of other functions including timing of the lock wait, wait interruptible lock, fairness, and the realization of the non-locking block structure. In terms of performance, in earlier versions of JDK5, the performance is much better than ReentrantLock synchronized, but from the beginning JDK6, JDK done a lot of optimization on a synchronized, so that the performance gap between the two is unlikely. Synchronized advantage is simplicity. Therefore, the choice between the two will depend on the specific needs, ReentrantLock can be used as an advanced tool for when you need some of the advanced features you can use it.

Published 305 original articles · won praise 46 · views 290 000 +

Guess you like

Origin blog.csdn.net/kaikai_sk/article/details/88697831