`

ReentrantLockd的其他方法源码解读

阅读更多
//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;
    }

   //查询是否有线程等待在该条件对上等待。
    public boolean hasWaiters(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
    }
   

    public final boolean hasWaiters(ConditionObject condition) {
     //判断该condition是否为当前sync所拥有
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.hasWaiters();
    }

    final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
            return sync == AbstractQueuedSynchronizer.this;
        }

    protected final boolean hasWaiters() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
	   //从头开始查找有没有waitStatus等于CONDITION的节点。有就说明有线程在该条件上等待
            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                if (w.waitStatus == Node.CONDITION)
                    return true;
            }
            return false;
        }


     //获取当前condition等待线程上的预估数
     public int getWaitQueueLength(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

    protected final int getWaitQueueLength() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            int n = 0;
            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                if (w.waitStatus == Node.CONDITION)
                    ++n;
            }
            return n;
        }  

     //获取该condition上等待的线程封装到Collection中
    protected Collection<Thread> getWaitingThreads(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

     protected final Collection<Thread> getWaitingThreads() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            ArrayList<Thread> list = new ArrayList<Thread>();
            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                if (w.waitStatus == Node.CONDITION) {
                    Thread t = w.thread;
                    if (t != null)
                        list.add(t);
                }
            }
            return list;
        }
分享到:
评论

相关推荐

    TMS320F28x源码解读 程序

    《TMS320F28x源码解读——深入理解数字信号处理器的精髓》 在数字信号处理领域,TMS320F28x系列芯片因其高性能、低功耗的特点,被广泛应用于各种复杂系统中,如工业自动化、电力控制、通信设备等。这些系统的核心...

    HashMap之put方法源码解读.docx

    HashMap 之 put 方法源码解读 HashMap 是 Java 中一种常用的数据结构,用于存储键值对。其中,put 方法是 HashMap 中最重要的方法之一,负责将键值对存储到HashMap 中。在本文中,我们将对 HashMap 的 put 方法的...

    Postgresql源码解读.docx

    4500页的源码解读 光是SELECT语句相关实现,就阐述了300多页 看完了你就是postgreSQL达人了 章节明细,需要精读那个功能点就仔细看

    Netty5.0架构剖析和源码解读.pdf

    Netty5.0架构剖析和源码解读 本文档主要讲述了Netty5.0架构剖析和源码解读,涵盖了Netty的架构、源码分析、NIO入门等方面的知识点。 概述 JAVA 的 IO 演进是一个长期的过程,从传统的 BIO 通信到 NIO 的出现,都...

    源码解读:参照管理系统的功能实现.pptx

    源码解读是软件开发中的一项重要技能,它涉及到对程序源代码的深入理解和分析,以揭示系统的功能实现和设计思路。在《源码解读的基本原理》中,我们了解到源码解读能够帮助我们理解系统的运作机制,提升编程能力,并...

    菜鸟 Spring 源码解读 推荐流程

    Spring框架的设计理念和实现方式对许多其他Java框架产生了深远影响,因此深入理解Spring源码对于提升整体编程技能至关重要。 Spring框架主要由以下几个模块组成: 1. **核心容器**:这是Spring的基石,包括...

    Spark源码深度解读

    Spark源码解读迷你 RDD、Spark Submit、Job、Runtime、Scheduler、Spark Storage、Shuffle、Standlone算法、Spark On yarn。。。

    netty5.0架构剖析和源码解读

    Netty5.0架构剖析和源码解读,旨在为读者提供深入理解Netty内部工作机制的途径,通过源码层面的分析帮助开发者更好地掌握Netty的应用和优化。 1. JAVA的IO演进 在Netty 5.0之前,Java IO主要经历了BIO到NIO的演进...

    jQuery源码解读

    jQuery 源码解读 jQuery 是一款非常流行的 JavaScript 库,以其简洁的语法和强大的功能深受开发者喜爱。本文将深入探讨 jQuery 的源码结构和执行流程,帮助你更好地理解和运用这个库。 首先,jQuery 的核心架构是...

    Resin源码解读1

    《Resin源码解读》 Resin,作为一个高性能的Java应用服务器,其源码解析对于我们深入理解Web服务器的运行机制和优化技术具有重要的价值。本文将从日志分析、运行时调试、网络模型以及线程池模型四个方面进行深入...

    Netty5.0架构剖析和源码解读.PDF

    在源码解读方面,我们可以关注以下几个关键部分: 1. **BossGroup 和 WorkerGroup 的实现**:通常基于NIO的Selector实现,BossGroup负责监听新连接,而WorkerGroup处理已连接的SocketChannel。 2. **Channel 实现*...

    PX4源码解读

    在《PX4源码解读》中,我们可以深入探讨这个系统的核心组成部分和工作原理。首先,PX4的架构由几个关键模块组成: 1. **硬件抽象层**:这层代码确保了PX4可以适应各种硬件平台,包括不同类型的传感器、处理器和通信...

    Spark-2.3.1源码解读

    Spark-2.3.1源码解读。 Spark Core源码阅读 Spark Context 阅读要点 Spark的缓存,变量,shuffle数据等清理及机制 Spark-submit关于参数及部署模式的部分解析 GroupByKey VS ReduceByKey OrderedRDDFunctions...

    VxWorks源码解读.rar

    VxWorks以其高效、确定性和微秒级的响应时间著称,它的源码解读对于我们理解其工作原理、优化系统性能以及进行定制化开发具有重要意义。 首先,我们要了解VxWorks的核心组成部分,包括内核(Kernel)、文件系统...

    JEECMS2源码的解读

    JEECMS2源码的解读,介绍JEECMS2源码的结构,开发流程等

    Pixhawk源码总结.rar_pixhawk_pixhawk代码解读_pixhawk源码_开源飞控

    综上所述,“Pixhawk源码总结.pdf”这份文档详细介绍了Pixhawk的软件架构、关键算法以及源码解读,对于想要深入学习开源飞控系统的人来说,是一份宝贵的参考资料。通过阅读和实践,开发者可以更好地掌握无人机飞行...

    Vue进阶面试题,源码解读,含Vue3源码解读

    本文将针对"Vue进阶面试题,源码解读,含Vue3源码解读"这一主题,详细探讨相关知识点。 首先,对于Vue进阶面试题,通常会涉及到以下几个方面: 1. **响应式原理**:Vue基于ES6的Proxy和Reflect实现数据的响应式,...

    第三节-springboot源码解析-王炸篇.pdf

    @RequestMapping注解用于映射Web请求到相应的处理方法上。 总而言之,通过对Spring Boot源码的解析,可以了解到Spring Boot是如何简化Spring应用的配置和部署的,其中涉及到的自动装配、条件装配和自定义启动器等...

    struts2 源码解读

    这篇博文“Struts2源码解读”深入剖析了Struts2的核心机制,帮助开发者更好地理解和利用这个框架。源码分析是提升编程技能和解决问题的关键,特别是对于复杂的框架如Struts2,理解其内部工作原理能够帮助我们优化...

Global site tag (gtag.js) - Google Analytics