`
withoutme_hw
  • 浏览: 10058 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

ReentrantLock实现-学习笔记

 
阅读更多

    线程安全往往需要靠互斥锁机制来保证,ReentrantLock是比关键字sychronized更灵活的可重入互斥锁。ReentrantLock在不使用锁(它自己本身就是Lock)和synchronized关键字的前提下,是怎么保证线程安全的呢。

    看一下不公平锁实现的lock方法(调用的是Sync(NonfairSync)的lock方法

    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        /**
         * Performs lock.  Try immediate barge, backing up to normal
         * acquire on failure.
         */
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

    1. 先通过CAS原子操作来试图获取锁(当前状态==0并且成功的将状态改为1),如果CAS返回true,说明成功获取到锁,那么简单的将该锁的拥有线程设为当前线程即可返回。锁获取成功。

    2. 如果CAS返回false,则调用acquire方法,其中先调用tryAcquire方法,在不公平锁的实现中,tryAcuqire方法首先做的操作与lock方法的第一步操作基本重复,也是先通过CAS原子操作尝试获取锁,成功则设置所谓当前线程所有。如果当前的状态不为0(说明有线程已经获取到该锁),则判断持有该锁的是不是当前线程自身,如果是自身,由于是可重入锁,则简单的将当前状态计数+1就可返回,锁获取成功。

        

    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

 

       //tryAcquire 
       /**
         * Performs non-fair tryLock.  tryAcquire is
         * implemented in subclasses, but both need nonfair
         * try for trylock method.
         */
       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;
        }

      3. 如果不是上面这2种情况,则说明锁已经被其他线程排他占用,则调用addWaiter先将当前线程放入等待队列中,然后在acquireQueued方法中,循环判断是否已经轮到当前节点(即该节点前面没有可用节点),如果没有有效节点,则再尝试调用tryAcquire方法,失败则继续循环,否则成功获取到锁并返回。如果前面有其他节点,则将当前线程park,当前线程阻塞,可能直到其他线程unlock调用unpark,然后才恢复执行并重新试图获取该锁。

     //this method is implemented in AbstractQueuedSynchronizer
    /**
     * Acquires in exclusive uninterruptible mode for thread already in
     * queue. Used by condition wait methods as well as acquire.
     *
     * @param node the node
     * @param arg the acquire argument
     * @return {@code true} if interrupted while waiting
     */
    final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

 

分享到:
评论

相关推荐

    Java并发实践-学习笔记

    这份"Java并发实践-学习笔记"涵盖了这个关键主题,旨在帮助开发者深入理解和掌握Java中的并发机制。以下是对这份笔记可能包含的一些核心知识点的详细阐述: 1. **Java并发基础**:首先,笔记可能会介绍Java并发的...

    Java并发编程与高并发解决方案-学习笔记.pdf

    并发编程与高并发解决方案的学习笔记中,首先对并发与高并发进行了基本概念的介绍。并发指的是同时存在多个执行单元,但并不一定同时发生;而高并发是指系统能够同时处理很多的请求,这对于互联网分布式系统架构设计...

    个人学习-JUC-笔记

    本笔记主要围绕尚硅谷周阳老师的JUC课程展开,旨在帮助个人学习者深入理解和掌握Java并发编程的核心知识。 1. **并发基础** - **线程与进程**:线程是程序执行的最小单位,进程则是资源分配的基本单位。了解它们的...

    javaEE学习笔记

    ### Java/JavaEE 学习笔记关键知识点概览 #### 1. Unix 学习笔记 - **Unix 前言** - Unix 是一种多用户、多任务的操作系统,广泛应用于服务器领域。 - Unix 的历史和发展背景,以及其在现代IT基础设施中的重要性...

    Java基础尚硅谷宋红康学习笔记

    10. **Java并发编程**:包括线程池、锁机制(如synchronized、ReentrantLock)、并发容器(如ConcurrentHashMap、CopyOnWriteArrayList)以及并发工具类(如CountDownLatch、CyclicBarrier)。 这些是Java基础知识...

    JAVA 多线程学习笔记

    这篇学习笔记将深入探讨Java多线程的核心概念、实现方式以及相关工具的使用。 一、多线程基础 1. 线程与进程:在操作系统中,进程是资源分配的基本单位,而线程是程序执行的基本单位。每个进程至少有一个主线程,...

    Java并发编程学习笔记.rar

    这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...

    java学习笔记(下)

    ### Java学习笔记(下)——深入理解框架与核心技术 #### 物件容器(Container) 在Java中,物件容器是管理物件的重要工具,分为两大类:`Collection`与`Map`。 - **Collection类**:主要包含`List`与`Set`。`...

    多线程-狂神说Java学习笔记

    本学习笔记将深入探讨Java多线程的相关知识,包括其原理、实现方式、同步机制以及常见问题。 ### 一、多线程的基本概念 多线程是指在一个程序中存在两个或更多的执行线程,这些线程共享同一内存空间,但各自拥有...

    bjy学习笔记-阿里巴巴Java编码规范以及一些技术笔记

    在本压缩包“bjy学习笔记-阿里巴巴Java编码规范以及一些技术笔记”中,我们可以预见到包含的内容主要是关于Java编程语言的学习心得,特别是遵循阿里巴巴的Java编码规范的相关知识。这是一份宝贵的资源,对于Java...

    Java jdk1.7学习笔记pdf

    ### Java JDK 1.7 学习笔记核心知识点解析 #### 一、Java JDK 1.7 概述 在《Java JDK 1.7 学习笔记》这本书中,作者详细介绍了Java Development Kit (JDK) 1.7 的新特性与改进之处。Java 作为一门广泛使用的编程...

    1 JAVA学习笔记.zip

    这份"1 JAVA学习笔记.zip"包含了深入学习Java编程的重要资料,对于初学者和有经验的开发者来说都是宝贵的资源。 1. **Java基础** - **数据类型**: Java分为两种数据类型:基本类型和引用类型。基本类型包括整型...

    java学习笔记

    ### Java学习笔记知识点详解 #### 一、Java基础知识概述 Java是一种广泛使用的面向对象的编程语言,具有简单性、面向对象、健壮性、安全性、平台独立性、可移植性等特点。Java的基本知识包括以下几个方面: 1. **...

    java学习笔记-基础

    ### Java学习笔记——基础知识详解 #### 一、Java开发环境(JDK)与运行环境(JRE) Java技术的核心在于其强大的跨平台能力,这主要得益于Java的两大环境:JDK(Java Development Kit)和JRE(Java Runtime ...

    Java基础学习笔记.zip

    这份"Java基础学习笔记.zip"包含了多个主题,涵盖了Java语言的基础到进阶内容,非常适合初学者和有经验的开发者复习巩固。 首先,我们来看"day03【List、Set】-笔记.pdf",这部分主要讲解了Java集合框架中的两种...

    Java架构面试专题汇总(含答案)和学习笔记.zip

    - 线程同步:synchronized关键字,wait()、notify()和notifyAll()方法,Lock接口及ReentrantLock实现。 - 死锁、活锁与饥饿现象的识别与避免。 4. **并发编程** - java.util.concurrent包中的工具类,如...

    良葛格 Java 学习笔记-JavaGossip全(v1+v2)

    《良葛格 Java 学习笔记-JavaGossip全(v1+v2)》是一部集成了作者良葛格多年编程经验的学习资料,旨在帮助初学者和有经验的开发者深入理解和掌握Java这门强大的编程语言。这份笔记包含了JavaGossip的两个版本,v1和...

    Java架构面试专题(含答案)和学习笔记(5).rar

    这个压缩包文件包含的学习笔记和答案,旨在帮助读者深入理解Java技术栈的关键点,提升解决问题的能力。以下是对Java架构面试中可能出现的一些关键知识点的详细说明: 1. **JVM(Java虚拟机)**: - 类加载机制:...

    基于java的开发源码-多线程反射泛型及正则表达式学习笔记和源码.zip

    在"基于java的开发源码-多线程反射泛型及正则表达式学习笔记和源码.zip"这个压缩包中,包含了三个关键的Java编程概念:多线程、反射和泛型,以及正则表达式。下面我们将详细探讨这些知识点。 1. **多线程**:多线程...

    JVM的学习笔记PDF版

    这份“JVM的学习笔记PDF版”应该包含了关于JVM的详细信息,帮助学习者深入理解这个复杂的系统。JVM允许Java代码跨平台运行,通过解释器、类加载器、垃圾收集器等组件实现“一次编写,到处运行”的理念。 1. **JVM...

Global site tag (gtag.js) - Google Analytics