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

java并发编程--AbstractQueuedSynchronizer公平锁和非公平锁分析(三)

阅读更多

juc包中,aqs实现的公平锁和非公平锁的最主要的区别是:非公平锁中,那些尝试获取锁且尚未进入等待队列的线程会和等待队列head结点的线程发生竞争。公平锁中,在获取锁时,增加了isFirst(current)判断,当且仅当,等待队列为空或当前线程是等待队列的头结点时,才可尝试获取锁。

 

 

1.1 NonfairSync.lock() 

final void lock() {
	if (compareAndSetState(0, 1))//没有进入等待队列,也可以获取锁
		setExclusiveOwnerThread(Thread.currentThread());
	else
		acquire(1);
}

 

2.1 FairSync.lock()

final void lock() {
        acquire(1);
}

 

2.2 FairSync.tryAcquire()

/**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (isFirst(current) &&//只有等待队列为空或当前线程是队列头结点才可以获取锁
                    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;
        }

关于当前线程是否是队列头结点的判断,详见下面两个函数: 

 

2.3 AbstractQueuedSynchronizer.isFirst()

/**
     * Return {@code true} if the queue is empty or if the given thread
     * is at the head of the queue. This is reliable only if
     * <tt>current</tt> is actually Thread.currentThread() of caller.
     */
    final boolean isFirst(Thread current) {
        Node h, s;
        return ((h = head) == null ||
                ((s = h.next) != null && s.thread == current) ||
                fullIsFirst(current));
    }

 

2.4 AbstractQueuedSynchronizer.fullIsFirst()

final boolean fullIsFirst(Thread current) {
        // same idea as fullGetFirstQueuedThread
        Node h, s;
        Thread firstThread = null;
        if (((h = head) != null && (s = h.next) != null &&
             s.prev == head && (firstThread = s.thread) != null))
            return firstThread == current;
        Node t = tail;
        while (t != null && t != head) {
            Thread tt = t.thread;
            if (tt != null)
                firstThread = tt;
            t = t.prev;
        }
        return firstThread == current || firstThread == null;
    }
 

总结:

线程为首结点成立的情况:

1.等待队列为空。

2.等待队列head的next结点的thread为当前线程(head.next.thread = currentThread),即线程为等待队列除哑结点外的第一个结点。

3.等待队列head结点到某个结点(暂命名为结点s),之间的所有结点的thread变量为null,且结点s的thread为当前线程。

 

分享到:
评论
1 楼 nmgrd 2017-04-23  
赞一个,在分析AQS源码的博客当中,楼主是写的最细致,最易懂,最走心的,本人评论时间是20170423,截止目前,本人还没发现其他更好的AQS源码分析

相关推荐

    Java并发编程全景图.pdf

    Java并发编程是Java语言中最为复杂且重要的部分之一,它涉及了多线程编程、内存模型、同步机制等多个领域。为了深入理解Java并发编程,有必要了解其核心技术点和相关实现原理,以下将详细介绍文件中提及的关键知识点...

    Java 并发编程实战.pdf

    通过本书,读者可以系统地掌握Java并发编程的原理和实践技巧。 由于本书的具体内容未完全提供,我将根据标题和描述,以及作为一名IT行业专家对Java并发编程知识的理解,来详细阐述相关知识点。 首先,Java的并发...

    第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock()1

    ReentrantLock作为Java并发编程中的重要工具,它的灵活性和高效性使得它在多线程环境下被广泛使用。本篇文章将深入解析ReentrantLock的源码,重点讨论非公平锁和公平锁的获取过程。 1. **ReentrantLock的基本概念**...

    Java并发编程学习笔记

    可重入锁是Java.util.concurrent.locks包下的ReentrantLock类,支持公平锁和非公平锁,具有比synchronized更细粒度的控制。它提供tryLock()方法,可以在无法获取锁时立即返回,而不是等待。 3. **ThreadLocal**: ...

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

    在深入ReentrantLock之前,我们首先需要了解Java并发编程的基础,特别是Java内存模型和线程同步机制。 **可重入锁与可重入性** 可重入锁允许同一个线程反复进入它已经拥有的锁所保护的代码段。在Java中,...

    Java 多线程与并发(10-26)-JUC锁- 锁核心类AQS详解.pdf

    独占式又分为公平锁和非公平锁,公平锁按照线程在队列中的等待顺序获取锁,而非公平锁则不管线程等待顺序,谁先到达就让谁尝试获取锁。 AQS的acquire方法用于线程以独占模式获取资源,若资源被其他线程占有,则线程...

    Java-JUC-多线程 进阶

    Java-JUC-多线程进阶 Java-JUC-多线程进阶resources是 Java 并发编程的高级课程,涵盖...公平锁和非公平锁是 Java 中的两种锁机制,公平锁按照线程的请求顺序提供锁,非公平锁按照线程的请求顺序和锁的可用性提供锁。

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

    在Java多线程并发编程中,ReentrantReadWriteLock(可重入读写锁)是一个重要的同步工具,它属于Java并发包(java.util.concurrent.locks)中的一个类。这个锁提供了比标准的synchronized关键字更细粒度的控制,允许...

    Java并发编程与高并发解决方案.txt

    例如,它可以支持公平锁和非公平锁,还可以支持尝试获取锁,即在指定时间内没有获取到锁则返回失败。 ##### 3.2 CountDownLatch `CountDownLatch`是一个同步辅助类,它允许一个或多个线程等待其他线程完成操作。...

    Java并发编程实战

    Java并发编程实战 本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及...

    Java并发编程面试题(2024最新版)-重点.docx

    ### Java并发编程面试题知识点详解 #### 一、基础知识与概念 **1. 并发编程的优缺点:** - **优点:** - **提高性能:**通过多个任务同时执行,可以有效利用多核处理器资源,提升整体系统的吞吐量。 - **响应性:...

    java锁详解.pdf

    2. 锁的分类:ReentrantLock 锁可以分为公平锁和非公平锁两种。 3. 公平锁:公平锁是 ReentrantLock 锁的一种实现方式,确保线程按顺序获得锁。 4. 非公平锁:非公平锁是 ReentrantLock 锁的一种实现方式,允许线程...

    【并发编程】简单化理解AQS和ReentrantLock.pdf

    AQS和`ReentrantLock`是Java并发编程中重要的组成部分,通过对它们的理解和掌握,可以更好地设计和实现高性能的并发程序。通过本文的学习,读者可以了解到这些核心概念和技术的实际应用,并能够根据具体的业务需求...

    Java互联网架构多线程并发编程原理及实战 视频教程 下载.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载4.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载2.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载3.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载1.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    基于JDK源码解析Java领域中的并发锁之设计与实现.pdf

    典型的Lock实现如ReentrantLock,它支持公平锁和非公平锁,以及可重入和可中断的特性。 五、ReadWriteLock接口的设计与实现 ReadWriteLock接口代表读写锁,它允许多个读取者同时访问资源,但在写入时确保互斥。典型...

    并发编程面试题(2020最新版)

    并发编程是当今软件开发中...重入锁(ReentrantLock)是Java中支持可重入的锁,它支持公平锁和非公平锁两种策略。读写锁ReentrantReadWriteLock允许多个读线程同时访问,而在写线程访问时,读线程和写线程都会被阻塞。

Global site tag (gtag.js) - Google Analytics