`
suichangkele
  • 浏览: 199744 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

juc - ReentrantLock源码解读(二)

    博客分类:
  • java
阅读更多

上一篇介绍了不公平的重入锁,那什么是公平,什么是不公平呢?仅仅通过第一篇博客可以回答这个问题的,但是往往我们会忽略掉这个问题,看一下公屏和不公平的差别在哪里能勾引起我们更多的思考,这样就能解释什么是公平、非公平了。(在继续看这篇博客之前,请一定要读一下http://suichangkele.iteye.com/blog/2368173 这个博客)。

在ReentrantLock的构造方法中,如果没有设置参数,默认就是不公平的,如果设置为true,则会生成一个FairSync的同步器,我们看一下他和NonFairSync的差别的地方吧:

static final class NonfairSync extends Sync {//不公平的
        private static final long serialVersionUID = 7316153563782823691L;

        final void lock() {//在调用lock的时候上来就会查看当前的标记是否是0,
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }
        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);//这个方法也是先看标记是不是0,如果是的话就会调用compareAndSetState(0,1),尽管此时可能有阻塞的线程在队列中。
        }
    }

    static final class FairSync extends Sync {//公平的
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {//在调用lock的时候不会查看标记是不是0,而是直接调用acquire,也就是先调用tryAcquire(acquire中就是先调用的tryAcquire方法)
            acquire(1);
        }
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {//这个地方就是关键点,如果当前的锁没有被占用(此时可能有排队等待的线程),
                if (!hasQueuedPredecessors()//公平和不公平就体现在这里,公平的会看当前的队列中是否存在已经排队的线程,如果有的话就不会捕获锁,尽管锁当前没有被占有,如果没有等待者,才会捕获锁。
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }

 

看完上面的代码可能大概的意思就懂了:由于这一种情况的存在,即:占有锁的线程释放了锁,但是被队列中等待的线程捕获锁之前,又有新的线程来获得锁,它可能会比队列中的线程领先获得锁。在这种情况里,就体现了公平非公平。如果是公平的,那么新的线程就会检查队列中是否已经存在了等待的线程,也就是FairSync的tryAcquire方法中hasQueuedPredecessors的判断,如果是,那新的线程就不能获得锁,将锁让给已经等待的线程。如果是非公平的,即在新线程获得锁时不关心是否存在等待的线程,直接尝试调用compareAndSetState(0, 1)方法,也就是获得锁的方法,此时如果获得了锁,尽管之前刚刚释放锁的线程已经唤醒了等待的线程,等待的线程会继续进行for循环,进入到第一个if判断中,但是没有tryAcquire成功,所以就会继续被挂起(这段代码在http://suichangkele.iteye.com/blog/2368173中)。

 

好了,很简单的就完成了公平锁的研究。。。。

 

分享到:
评论

相关推荐

    Java 多线程与并发(11-26)-JUC锁- ReentrantLock详解.pdf

    Java中的ReentrantLock是Java并发包(java.util.concurrent.locks)中的一个高级锁,它是可重入的,意味着一个线程可以多次获取同一锁。在深入ReentrantLock之前,我们首先需要了解Java并发编程的基础,特别是Java...

    tuling-juc-final.zip

    本项目"tuling-juc-final.zip"显然聚焦于Java并发编程的实践,通过一系列代码示例来演示和解释Java内存模型(JMM)、`synchronized`关键字以及`volatile`关键字的使用。下面我们将深入探讨这些核心概念。 Java内存...

    java并发编程专题(五)----详解(JUC)ReentrantLock

    Java并发编程中的ReentrantLock是Java并发包(java.util.concurrent,简称JUC)中的一个重要的锁机制,它是Lock接口的一个具体实现,提供了比synchronized更强大的锁定功能和更细粒度的控制。ReentrantLock的主要...

    Java-JUC-多线程 进阶

    Java-JUC-多线程进阶 Java-JUC-多线程进阶resources是 Java 并发编程的高级课程,涵盖了 Java 中的并发编程概念、线程安全、锁机制、集合类、线程池、函数式接口、Stream流式计算等多个方面。 什么是JUC JUC...

    个人学习-JUC-笔记

    Java并发编程是Java开发中的重要领域,而JUC(Java Util Concurrency)是Java平台提供的一套高级并发工具包,它极大地简化了多线程和并发控制的复杂性。本笔记主要围绕尚硅谷周阳老师的JUC课程展开,旨在帮助个人...

    heima-JUC-资料

    4. **锁**:`ReentrantLock`是可重入的互斥锁,比`synchronized`关键字更强大,支持公平性、中断和定时等待。`ReadWriteLock`提供了读写锁,允许多个读取者同时访问,但写入操作是互斥的。 5. **原子变量**:`...

    Java 多线程与并发(7-26)-JUC - 类汇总和学习指南.pdf

    "Java 多线程与并发(7-26)-JUC - 类汇总和学习指南" Java 多线程与并发是 Java 编程语言中的一部分,用于处理多线程和并发编程。Java 提供了一个名为 JUC(Java Utilities for Concurrency)的框架,用于帮助开发者...

    juc-study编程笔记.md

    学习狂神说的juc编程的笔记

    A-JUC-JVM-Java并发知识..pdf

    ### JUC并发编程 #### JUC多线程及高并发 Java并发编程包(java.util.concurrent,简称JUC)封装了大量用于高并发编程的工具类和接口,其中涉及了线程池、阻塞队列、同步器、原子操作类等。在并发环境下,可以有效...

    juc-jenkins-2018:JUC Jenkins 2018演示源代码

    juc-jenkins-2018 JUC Jenkins 2018演示源代码 先决条件 为了运行此演示,必须有一个有效的JDK,git命令以及curl。 克隆存储库 将此存储库克隆到您家中的某个位置: git clone ...

    juc-1(2).docx

    【JUC 概念】 Java Util Concurrency (JUC) 是 Java SDK 中的一个核心包,位于 `java.util.concurrent` 下,它提供了丰富的线程同步和并发工具类,旨在简化多线程编程,提高程序的并发性能。JUC 包含了线程池、并发...

    juc_nio_linux.rar

    Java并发编程库(Java Util Concurrency,简称JUC)是Java平台中用于高效并发处理的重要工具,它提供了线程池、锁、原子变量等高级并发工具。在Java中,`java.util.concurrent`包包含了大量并发控制和并行计算的类与...

    juc-learn:juc相关源码的分析以及使用介绍

    本项目"juc-learn"专注于JUC相关源码的分析和使用介绍,旨在帮助开发者深入理解并熟练运用这些并发工具。 1. **并发基础** 在Java中,多线程是并发编程的基础。通过创建Thread对象或实现Runnable接口,我们可以...

    JUC-3 微程序控制计算机系列实验资源

    微程序控制器实验1. 连接好实验线路,检查无误后接通电源。2. 将编程开关(MJ20)置为PROM(编程)状态。3. 将STATE UNIT中的STEP置为“STEP”状态,STOP置为“RUN”状态。4. 在UA5-UA0开关上置要写的某个微地址(八进制)...

    免费开源!!主要是Java技术栈的文章

    1、Java并发体系-第一阶段-多线程基础知识 2、Java并发体系-第二阶段-锁与同步-[1] 3、Java并发体系-第二阶段-锁与同步-[2] 4、Java并发体系-第二阶段-锁与同步-[3] ...7、Java并发体系-第四阶段-AQS源码解读-[1]

    juc-demo:JUC包下常用工具练习Demo

    juc-demo JUC包下常用工具练习Demo 内容: 1、Semaphore 2、CountDownLatch 3、CyclicBarrier 4、ReentrantLock + Condition实现阻塞队列 Created by @minghui.y.

    JUC-master

    《JUC:Java并发编程的艺术》 在Java世界中,JUC(Java Util Concurrency)是并发编程的核心库,它提供了丰富的...通过深入学习JUC-master项目,我们可以更深入地理解Java并发编程的原理和实践,提升我们的编程技能。

    JUC线程高级

    JUC线程高级,

    JUC并发编程与源码分析视频课.zip

    《JUC并发编程与源码分析视频课》是一门深入探讨Java并发编程的课程,主要聚焦于Java Util Concurrency(JUC)库的使用和源码解析。JUC是Java平台提供的一组高级并发工具包,它极大地简化了多线程编程,并提供了更...

    22 尚硅谷Java JUC线程高级视频

    教程视频:在 Java 5.0 提供了 java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常用的工具类, 用于定义类似于线程的自定义子系统,包括线程池,异步 IO 和轻量级任务框架;还提供了设计用于多线程上下文...

Global site tag (gtag.js) - Google Analytics