ReentrantLockd的其他方法源码解读_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > ReentrantLockd的其他方法源码解读

ReentrantLockd的其他方法源码解读

 2017/7/28 5:33:08  红领巾丶  程序员俱乐部  我要评论(0)
  • 摘要://Reentrant的其他方法://先看lockInterruptibly方法,该方法主要用于如果该线程未被中断则获取锁publicvoidlockInterruptibly()throwsInterruptedException{sync.acquireInterruptibly(1);}publicfinalvoidacquireInterruptibly(intarg)throwsInterruptedException{//如果当前线程已经被中断抛出异常if(Thread
  • 标签:方法 源码 其他 Ant
class="java" name="code">

//Reentrant的其他方法:
//先看lockInterruptibly方法,该方法主要用于如果该线程未被中断则获取锁
 public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

     public final void acquireInterruptibly(int arg)
            throws InterruptedException {
	 //如果当前线程已经被中断抛出异常
        if (Thread.interrupted())
            throw new InterruptedException();
	 //尝试获取锁
        if (!tryAcquire(arg))
	    //没有获取到锁
            doAcquireInterruptibly(arg);
    }


private void doAcquireInterruptibly(int arg)
        throws InterruptedException {
	//入队
        final Node node = addWaiter(Node.EXCLUSIVE);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
		    //被中断抛出异常
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

 /**
 该方法和lock()方法大部分过程都相同最主要是新增了中断的判断。
 刚开始尝试获得锁的时候判断当前线程是否已经被中断。
 入队后,挂起当前线程的时候又会判断当前线程是否已经被中断。
 两次判断。其余流程与lock()一致。
 */


 //看tryLock方法,尝试获取锁成功返回true,失败返回false。
 public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }
  
final boolean nonfairTryAcquire(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) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

/**该方法即尝试获取锁,获取成功返回true,失败返回false*/


//看trylock的重载方法
 public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }

     public final boolean tryAcquireNanos(int arg, long nanosTimeout)
            throws InterruptedException {
	  //如果线程被中断抛出异常
        if (Thread.interrupted())
            throw new InterruptedException();
	  //尝试获取锁
        return tryAcquire(arg) ||

            doAcquireNanos(arg, nanosTimeout);
    }

    private boolean doAcquireNanos(int arg, long nanosTimeout)
        throws InterruptedException {
        long lastTime = System.nanoTime();
	//入队
        final Node node = addWaiter(Node.EXCLUSIVE);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return true;
                }
		//超时了
                if (nanosTimeout <= 0)
                    return false;
                if (shouldParkAfterFailedAcquire(p, node) &&
		    //nanosTimeout>1秒才挂起.因为时间太短的话可能挂起的时间已经超过自旋的时间。
                    nanosTimeout > spinForTimeoutThreshold)
		    //挂起当前线程
                    LockSupport.parkNanos(this, nanosTimeout);
		    //计算时间
                long now = System.nanoTime();
                nanosTimeout -= now - lastTime;
                lastTime = now;
                if (Thread.interrupted())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    /** 该方法时指在指定时间内获得锁*/


    //getHoldCount()返回当前线程保持该锁的次数
    public int getHoldCount() {
        return sync.getHoldCount();
    }

     final int getHoldCount() {
            //当前线程是独占线程
            return isHeldExclusively() ? getState() : 0;
        }
    //返回是否是独占方式调用的线程
     protected final boolean isHeldExclusively() {
            return getExclusiveOwnerThread() == Thread.currentThread();
        }


   //isHeldByCurrentThread() 查询当前线程是否拥有此锁
   public boolean isHeldByCurrentThread() {
        return sync.isHeldExclusively();
    }
    protected final boolean isHeldExclusively() {
            return getExclusiveOwnerThread() == Thread.currentThread();
        }

   //isLock()查询锁是否已经被拥有
   public boolean isLocked() {
        return sync.isLocked();
    }
     final boolean isLocked() {
            return getState() != 0;
        }

   //isFair() 判断该锁是否为公平锁
   public final boolean isFair() {
        return sync instanceof FairSync;
    }

   //getOwner()返回拥有当前锁的线程
    protected Thread getOwner() {
        return sync.getOwner();
    }
   /**
   这个方法有些奇怪为什么要判断getState不直接getExclusiveOwnerThread()?
   因为 private volatile int state; state是volatile的,是安全的。
   而 private transient Thread exclusiveOwnerThread。没有volatile关键字没有保证内存可见性。
   */
    final Thread getOwner() {
            return getState() == 0 ? null : getExclusiveOwnerThread();
        }

   //判断是否有线程队列在等待此锁
   public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }
    /**在线程入队的时候,如果队列为空,会初始化一个节点作为头节点和尾节点。
    所以如果头结点和尾节点相等表示没有中间节点即队列为空。
    */
    public final boolean hasQueuedThreads() {
        return head != tail;
    }


   //查询给定线程是否在等待此锁
   public final boolean hasQueuedThread(Thread thread) {
        return sync.isQueued(thread);
    }

    public final boolean isQueued(Thread thread) {
        if (thread == null)
            throw new NullPointerException();
	 //从队伍开始查找此线程
        for (Node p = tail; p != null; p = p.prev)
            if (p.thread == thread)
                return true;
        return false;
    }


  //getQueueLength()返回正在等待该锁的线程估计数
   public final int getQueueLength() {
        return sync.getQueueLength();
    }

   public final int getQueueLength() {
        int n = 0;
	//从队尾开始像前搜索
        for (Node p = tail; p != null; p = p.prev) {
            if (p.thread != null)
                ++n;
        }
        return n;
    }

    //getQueuedThreads()获取正在等待的所有线程封装到ArrayList中
    protected Collection<Thread> getQueuedThreads() {
        return sync.getQueuedThreads();
    }
    public final Collection<Thread> getQueuedThreads() {
        ArrayList<Thread> list = new ArrayList<Thread>();
	//从队尾开始遍历所有节点
        for (Node p = tail; p != null; p = p.prev) {
            Thread t = p.thread;
            if (t != null)
                list.add(t);
        }
        return list;
    }
发表评论
用户名: 匿名