并发编程原理与实战(三十二)AQS核心机制与使用示例解读

CAS、CAS自旋、CAS自旋锁、CLH锁与Java AQS:深入理解并发编程核心机制 CAS(Compare and Swap)是一种无锁(Lock-Free)的原子操作,用于在多线程环境下实现数据同步。CLH(Craig, Landin, Hagersten)锁是一种基于链表的队列锁,通过隐式队列管理线程,减少缓存一致性流量。基于CAS自旋实现的锁,线程在获取锁失败时不会阻塞,而是循环尝试。理解这些机制的原理与实现,是编写高效、健壮并发代码的关键。CAS自旋是指线程在CAS失败后循环重试,直到成功。)的核心框架,用于构建锁和同步器(如。AQS提供需子类实现的抽象方法(如。 阅读详情

前面的系列文章,我们主要学习了线程基础、线程并发协同工具类、线程安全、锁、原子类等内容。有了前面的这些知识,接下来我们来学习Java并发编程中线程协作工具统一的底层框架AbstractQueuedSynchronizer,简称AQS。

认识AQS

首先,AbstractQueuedSynchronizer是一个抽象类。

public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {
    ...
}

AQS通过抽象队列式同步机制,为ReentrantLock、Semaphore等并发工具提供了统一的底层框架。这些工具虽然功能各异(如独占锁、信号量等),但都需要解决线程阻塞、唤醒及资源状态管理的共性问题。AQS将这类共性逻辑(如队列管理、状态原子操作)封装为通用模板,避免了每个工具类重复实现这些复杂逻辑。既然是一个抽象类,那么就有子类去实现,官方对该类的子类的实现做出了详细说明。

子类实现规范

/**
 * Provides a framework for implementing blocking locks and related
 * synchronizers (semaphores, events, etc) that rely on
 * first-in-first-out (FIFO) wait queues.  This class is designed to
 * be a useful basis for most kinds of synchronizers that rely on a
 * single atomic {@code int} value to represent state. Subclasses
 * must define the protected methods that change this state, and which
 * define what that state means in terms of this object being acquired
 * or released.  Given these, the other methods in this class carry
 * out all queuing and blocking mechanics. Subclasses can maintain
 * other state fields, but only the atomically updated {@code int}
 * value manipulated using methods {@link #getState}, {@link
 * #setState} and {@link #compareAndSetState} is tracked with respect
 * to synchronization.
 */

本类为基于先进先出(FIFO)等待队列的阻塞锁及相关同步器(信号量、事件等)提供实现框架。该类设计适用于大多数依赖单个原子整型变量表示状态的同步器场景。子类需通过以下方式实现定制化:

(1)状态定义:子类必须实现受保护的方法来修改状态变量,并定义该状态值在对象获取/释放操作中的具体含义(如0表示未锁定,1表示锁定)‌。

(2)核心机制:本类提供所有队列管理和阻塞机制的实现,包括:等待队列的FIFO调度,线程阻塞/唤醒控制,原子状态变更操作。

(3)状态管理规范:仅通过getState()、setState()和compareAndSetState()方法操作的原子整型变量受同步机制保护。

 /* <p>Subclasses should be defined as non-public internal helper
 * classes that are used to implement the synchronization properties
 * of their enclosing class.  Class
 * {@code AbstractQueuedSynchronizer} does not implement any
 * synchronization interface.  Instead it defines methods such as
 * {@link #acquireInterruptibly} that can be invoked as
 * appropriate by concrete locks and related synchronizers to
 * implement their public methods.
 */

子类应定义为非公开的内部辅助类,用于实现其外围类的同步特性。类AbstractQueuedSynchronizer并未实现任何同步接口。相反,它定义了诸如acquireInterruptibly等方法,这些方法可由具体的锁及相关同步器在需要时调用,以实现其公共方法。

独占或共享模式

 /* <p>This class supports either or both a default <em>exclusive</em>
 * mode and a <em>shared</em> mode. When acquired in exclusive mode,
 * attempted acquires by other threads cannot succeed. Shared mode
 * acquires by multiple threads may (but need not) succeed. This class
 * does not &quot;understand&quot; these differences except in the
 * mechanical sense that when a shared mode acquire succeeds, the next
 * waiting thread (if one exists) must also determine whether it can
 * acquire as well. Threads waiting in the different modes share the
 * same FIFO queue. Usually, implementation subclasses support only
 * one of these modes, but both can come into play for example in a
 * {@link ReadWriteLock}. Subclasses that support only exclusive or
 * only shared modes need not define the methods supporting the unused mode.
 */

本类支持独占模式、共享模式或两者的组合。在独占模式下被获取时,其他线程的获取尝试将无法成功。共享模式下,多个线程的获取可能(但不一定)成功。此类仅在机械意义上理解这些差异:当共享模式获取成功时,下一个等待线程(如果存在)也必须判断自身是否也能获取。不同模式下的等待线程共享相同的FIFO队列。通常,实现子类仅支持其中一种模式,但两者可能同时发挥作用(例如在ReadWriteLock中)。仅支持独占或共享模式的子类无需定义未使用模式的相关方法。

Condition实现

 /* <p>This class defines a nested {@link ConditionObject} class that
 * can be used as a {@link Condition} implementation by subclasses
 * supporting exclusive mode for which method {@link
 * #isHeldExclusively} reports whether synchronization is exclusively
 * held with respect to the current thread, method {@link #release}
 * invoked with the current {@link #getState} value fully releases
 * this object, and {@link #acquire}, given this saved state value,
 * eventually restores this object to its previous acquired state.  No
 * {@code AbstractQueuedSynchronizer} method otherwise creates such a
 * condition, so if this constraint cannot be met, do not use it.  The
 * behavior of {@link ConditionObject} depends of course on the
 * semantics of its synchronizer implementation.
 */

本类定义了嵌套的ConditionObject类,对于支持独占模式的子类,可用作Condition实现。其中方法isHeldExclusively用于报告当前线程是否独占持有同步资源,方法release配合当前getState值可完全释放本对象,而acquire(给定保存的状态值)最终会将本对象恢复至先前获取状态。若此约束无法满足,请勿使用此条件。ConditionObject的行为当然取决于同步器实现的具体语义。

类功能说明与序列化特性

 /* <p>This class provides inspection, instrumentation, and monitoring
 * methods for the internal queue, as well as similar methods for
 * condition objects. These can be exported as desired into classes
 * using an {@code AbstractQueuedSynchronizer} for their
 * synchronization mechanics.
 *
 * <p>Serialization of this class stores only the underlying atomic
 * integer maintaining state, so deserialized objects have empty
 * thread queues. Typical subclasses requiring serializability will
 * define a {@code readObject} method that restores this to a known
 * initial state upon deserialization.
 */

该类提供对内部队列的检查、工具化及监控方法,同时也为条件对象提供类似功能。这些方法可根据需求导出到使用AbstractQueuedSynchronizer作为同步机制的类中。

本类的序列化仅存储维持状态的底层原子整数,反序列化后的对象将拥有空的线程队列。通常需要可序列化的子类会定义readObject方法,在反序列化时将状态恢复到已知初始状态。

使用方法

 /* <h2>Usage</h2>
 *
 * <p>To use this class as the basis of a synchronizer, redefine the
 * following methods, as applicable, by inspecting and/or modifying
 * the synchronization state using {@link #getState}, {@link
 * #setState} and/or {@link #compareAndSetState}:
 *
 * <ul>
 * <li>{@link #tryAcquire}
 * <li>{@link #tryRelease}
 * <li>{@link #tryAcquireShared}
 * <li>{@link #tryReleaseShared}
 * <li>{@link #isHeldExclusively}
 * </ul>
 
 * Each of these methods by default throws {@link
 * UnsupportedOperationException}.  Implementations of these methods
 * must be internally thread-safe, and should in general be short and
 * not block. Defining these methods is the <em>only</em> supported
 * means of using this class. All other methods are declared
 * {@code final} because they cannot be independently varied.
 */

若要将此类用作同步器的基础,需通过getState、setState和compareAndSetState方法检查和/或修改同步状态,并重新定义以下适用方法:

  • tryAcquire
  • tryRelease
  • tryAcquireShared
  • tryReleaseShared
  • isHeldExclusively

这些方法的默认实现均会抛出UnsupportedOperationException异常。这些方法的实现必须保证内部线程安全,且通常应保持简短且不阻塞。定义这些方法是使用本类的‌唯一‌支持方式。其他方法均声明为final,因为它们无法独立变化‌。

 /* <p>You may also find the inherited methods from {@link
 * AbstractOwnableSynchronizer} useful to keep track of the thread
 * owning an exclusive synchronizer.  You are encouraged to use them
 * -- this enables monitoring and diagnostic tools to assist users in
 * determining which threads hold locks.
 *
 * <p>Even though this class is based on an internal FIFO queue, it
 * does not automatically enforce FIFO acquisition policies.  The core
 * of exclusive synchronization takes the form:
 */

你可能还会发现从AbstractOwnableSynchronizer继承的方法对于跟踪拥有独占同步器的线程很有用。建议你使用这些方法 - 这使监控和诊断工具能够帮助用户确定哪些线程持有锁。

虽然此类基于内部FIFO队列实现,但它不会自动强制执行FIFO获取策略。独占同步的核心实现形式为:

//Acquire:
while (!tryAcquire(arg)) {
    //如果线程尚未入队,则将其入队;
    //可能阻塞当前线程。
}
//Release:
if (tryRelease(arg)) {
   //解除第一个排队线程的阻塞; 
}

加塞策略

 /* <p id="barging">Because checks in acquire are invoked before
 * enqueuing, a newly acquiring thread may <em>barge</em> ahead of
 * others that are blocked and queued.  However, you can, if desired,
 * define {@code tryAcquire} and/or {@code tryAcquireShared} to
 * disable barging by internally invoking one or more of the inspection
 * methods, thereby providing a <em>fair</em> FIFO acquisition order.
 * In particular, most fair synchronizers can define {@code tryAcquire}
 * to return {@code false} if {@link #hasQueuedPredecessors} (a method
 * specifically designed to be used by fair synchronizers) returns
 * {@code true}.  Other variations are possible.
 */

由于获取操作中的检查在入队前执行,新获取线程可能会加塞到其他阻塞线程之前。但如需禁用加塞行为,可通过在内部调用一个或多个检查方法(如tryAcquire和/或tryAcquireShared),从而实现公平的FIFO获取顺序。具体而言,多数公平同步器可将tryAcquire定义为:当hasQueuedPredecessors(专为公平同步器设计的方法)返回true时,返回false。其他变体实现也是可能的。

 /* <p>Throughput and scalability are generally highest for the
 * default barging (also known as <em>greedy</em>,
 * <em>renouncement</em>, and <em>convoy-avoidance</em>) strategy.
 * While this is not guaranteed to be fair or starvation-free, earlier
 * queued threads are allowed to recontend before later queued
 * threads, and each recontention has an unbiased chance to succeed
 * against incoming threads.  Also, while acquires do not
 * &quot;spin&quot; in the usual sense, they may perform multiple
 * invocations of {@code tryAcquire} interspersed with other
 * computations before blocking.  This gives most of the benefits of
 * spins when exclusive synchronization is only briefly held, without
 * most of the liabilities when it isn't. If so desired, you can
 * augment this by preceding calls to acquire methods with
 * "fast-path" checks, possibly prechecking {@link #hasContended}
 * and/or {@link #hasQueuedThreads} to only do so if the synchronizer
 * is likely not to be contended.
 */

默认加塞策略(亦称贪婪、放弃或避让策略)通常能提供最高吞吐量和可扩展性。虽然这不保证绝对公平或无饥饿,但早期排队线程可在后期排队线程前重新竞争,且每次重新竞争对新来线程具有均等成功机会。此外,获取操作虽非传统意义上的自旋,但在阻塞前可能交替执行多次tryAcquire调用及其他计算。当独占同步仅短暂持有时,这能获得自旋的大部分优势;当不持有时,则规避了大部分弊端。如需增强此特性,可在获取方法调用前添加快速路径检查,可能预检hasContended和/或hasQueuedThreads,仅当同步器不太可能发生争用时执行。

高效可扩展的基础

 /* <p>This class provides an efficient and scalable basis for
 * synchronization in part by specializing its range of use to
 * synchronizers that can rely on {@code int} state, acquire, and
 * release parameters, and an internal FIFO wait queue. When this does
 * not suffice, you can build synchronizers from a lower level using
 * {@link java.util.concurrent.atomic atomic} classes, your own custom
 * {@link java.util.Queue} classes, and {@link LockSupport} blocking
 * support.
 */

此类通过将使用范围限定为依赖int状态、获取/释放参数及内部FIFO等待队列的同步器,为同步操作提供了高效可扩展的基础。若此方案不足,可基于java.util.concurrent.atomic atomic类、自定义 java.util.Queue类及LockSupport阻塞支持构建更底层的同步器。

使用示例

以下是一个使用值0表示未锁定状态、1表示锁定状态的非可重入互斥锁类。虽然非可重入锁并不严格要求记录当前拥有线程,但本类仍然记录这些信息以便于监控使用情况。此外,该类还支持条件变量,并公开了一些监控方法:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

class Mutex implements Lock, java.io.Serializable {

    // 我们的内部辅助类
    private static class Sync extends AbstractQueuedSynchronizer {
        // 如果状态为零,则获取锁
        public boolean tryAcquire(int acquires) {
            assert acquires == 1; // 否则未使用
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        // 通过将状态设置为零来释放锁
        protected boolean tryRelease(int releases) {
            assert releases == 1; // 否则未使用
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        // 报告是否处于锁定状态
        public boolean isLocked() {
            return getState() != 0;
        }

        public boolean isHeldExclusively() {
            // 数据竞争,但因‘凭空保证’而安全
            return getExclusiveOwnerThread() == Thread.currentThread();
        }

        // 提供条件变量
        public Condition newCondition() {
            return new ConditionObject();
        }

        // 正常反序列化
        private void readObject(ObjectInputStream s)
                throws IOException, ClassNotFoundException {
            s.defaultReadObject();
            setState(0); // 重置为未锁定状态
        }
    }

    // The sync object does all the hard work. We just forward to it.
    private final Sync sync = new Sync();

    public void lock() {
        sync.acquire(1);
    }

    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    public void unlock() {
        sync.release(1);
    }

    public Condition newCondition() {
        return sync.newCondition();
    }

    public boolean isLocked() {
        return sync.isLocked();
    }

    public boolean isHeldByCurrentThread() {
        return sync.isHeldExclusively();
    }

    public boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }
}

下面这个类与CountDownLatch类似,但仅需单次signal触发。由于门闩是非独占的,因此使用共享的acquire和release方法。

class BooleanLatch {

    private static class Sync extends AbstractQueuedSynchronizer {
        boolean isSignalled() {
            return getState() != 0;
        }

        protected int tryAcquireShared(int ignore) {
            return isSignalled() ? 1 : -1;
        }

        protected boolean tryReleaseShared(int ignore) {
            setState(1);
            return true;
        }
    }

    private final Sync sync = new Sync();

    public boolean isSignalled() {
        return sync.isSignalled();
    }

    public void signal() {
        sync.releaseShared(1);
    }

    public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
}

总结

AQS的核心设计模式是‌模板方法模式‌,AQS将同步器的核心流程(如线程排队、阻塞唤醒)固化在父类中,仅将资源获取/释放的逻辑通过抽象方法(如tryAcquire、tryRelease)交给子类实现。基于AQS实现的同步器(锁实现类)核心规范:

(1)同步器(锁实现类)内部创建AbstractQueuedSynchronizer的子类。

(2)子类通过继承父类的getState、setState和compareAndSetState方法检查修改同步状态state;,并重新定义以下模板方法:

  • tryAcquire
  • tryRelease
  • tryAcquireShared
  • tryReleaseShared
  • isHeldExclusively
JAVA并发编程中AQS是什么? /独占方式。尝试获取资源,成功则返回true,失败则返回false。//独占方式。尝试释放资源,成功则返回true,失败则返回false。//共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。//共享方式。尝试释放资源,成功则返回true,失败则返回false。//该线程是否正在独占资源。只有用到condition才需要去实现它。 阅读详情

相关推荐

Java 锁机制全解析:从 synchronized 到 AQS,彻底搞懂并发编程的底层原理

本文深入解析Java并发编程中的锁机制,从基础到高级实现原理: 锁的必要性:通过计数器Bug示例展示多线程竞态条件问题,解释count++操作的非原子性本质。 synchronized详解: 三种使用方式:实例方法、静态方法和代码块 修复计数器问题的实现 可重入特性及实现原理(计数器机制) volatile作用: 解决多线程可见性问题 示例展示无volatile时的死循环问题 volatile保证内存可见性和禁止指令重排 底层机制: 对象头与Monitor实现原理 锁升级过程(偏向锁→轻量级锁→重量级锁)

ITaaaab的博客 694

AQS的核心原理分析

之前已经写过一篇关于AQS的介绍了,基本概念我就不多逼逼了,我直接把我那篇文章复制过来。后面来根据java的源码分析这个AQS的内部实现。 前言:这一部分的基础概念讲解,全部都是我之前的一篇博客:谈谈你对AQS的了解 1.写在前面: 这篇文章,我们来聊聊面试时一个比较有杀伤力的问题:聊聊你对AQS的理解? 之前有同学反馈,去互联网公司面试,面试官聊到并发时就问到了这个问题。当时那位同学内心估计受到了一万点伤害。。。因为首先,很多人可能连AQS是什么都不知道。或者仅仅是听说过AQS这个名词,但是可能连

oldshaui的博客 5250

Java并发编程之AQS

AQS是AbstractQueueSynchronizer是缩写,其意思就是抽象队列同步器。原理就是通过一个FIFO队列维护一个state同步状态值,只需要继承该抽象类重写对应的方法便可实现一套线程同步机制。AQS抽象类在java.util.concurrent.locks包下定义。如上图所示,AQS属于一个抽象类,主要是用来构建锁结构以及同步器的一个抽象类。AQS继承了AbstractOwnableSynchronizer,其作用为设置和获取独占锁的拥有者线程方法。

天天新知 2379

JAVA并发编程AQS原理剖析

很多小朋友面试时候,都会被面试官问:说一下AQS原理。面对并发编程基础和面试经验,拉丁解牛专栏采用通俗简洁无废话无八股文方式剖析原理和源码,让天下没有难啃的技术。

拉丁解牛技术专栏 1473

NVIDIA Orin AGX开发环境搭建避坑指南:从Ubuntu 22.04到ROS2完整配置流程

本文详细介绍了NVIDIA Orin AGX开发环境搭建的全流程,从Ubuntu 22.04系统安装到ROS2深度优化,涵盖驱动部署、CUDA环境配置、散热与功耗管理等关键步骤。特别针对Orin AGX的特性提供了实用避坑指南和性能优化技巧,帮助开发者高效完成开发环境配置。

weixin_28340315的博客 451

Python与numpy版本兼容性排查指南

本文详细解析了Python与numpy版本兼容性问题,提供了快速诊断和解决版本冲突的实用方法。通过查看版本信息、使用官方兼容性对照表以及降级或升级环境等方案,帮助开发者有效避免常见的报错问题,如'ImportError'和'AttributeError'。文章还介绍了使用虚拟环境和requirements.txt等工程实践,确保项目依赖的稳定性。

weixin_29089057的博客 319

Java并发编程——AQS原理解析

AQS原理解析,CountDownLatch, Semaphore和CyclicBarrier 详解

m0_62909831的博客 2164

Synopsys AXI VIP 从环境搭建到首个验证场景运行

本文详细介绍了Synopsys AXI VIP从环境搭建到首个验证场景运行的全过程,包括VIP安装、示例工程生成、验证环境解析、仿真调试技巧及进阶优化。特别针对AXI协议验证中的常见问题提供了实用解决方案,帮助工程师快速掌握这一SoC验证必备工具。

weixin_29185493的博客 340

深入剖析AQS:Java并发编程的核心基石与底层实现原理

即抽象的队列式同步器,是Java并发包(java.util.concurrent.locks)的核心基础框架。自JDK 1.5引入JUC包以来,AQS一直是Java并发编程体系的基石,其设计思想深刻影响了后续多版本JDK的并发实现。AQS采用模板方法设计模式,提供了一套完整的多线程访问共享资源的同步器实现方案。开发者可以基于此框架快速构建各种类型的同步器,而无需从头实现复杂的线程排队、唤醒机制。// 实现一个简单的二进制锁(不可重入)

用文字记录技术,用分享回馈社区,用坚持见证成长 1299

关于并网继电器的继电器自检逻辑及实现方式

对于常规的光伏并网逆变器来说,继电器控制至关重要。继电器一般位于逆变电感后,共模电感前,用于将逆变电压与电网电压脱开,一般国外有双继电器的安规强制认证要求,国内目前只需要单继电器要求(后续应该会有双继电器要求,个人感觉)

weixin_29982209的博客 2612

提示词编写:从新手到专家的进阶之路

本文旨在为提示词编写者提供一条从新手到专家的进阶之路。我们将详细探讨提示词编写的背景与意义、基础与进阶技巧、实战应用以及最佳实践。通过逐步深入的分析与实操,读者将掌握提示词编写的核心要点,提高编写效率和作品质量。提示词是用于引导人工智能生成文本的关键词或短语,它包含了作者想要传达的主题、情感和细节。随着人工智能技术的普及,自动化写作工具逐渐应用于各行各业。为了提高写作效率,项目团队决定开发一款基于人工智能的自动化写作工具。成功开发了一款自动化写作工具,生成文本质量较高。

AI天才研究院 1085

Java AQS:并发编程的核心机制

AQS 即 AbstractQueuedSynchronizer,是 Java 并发包中的一个抽象类,它提供了一种实现同步器的框架。同步器可以用于实现锁、信号量、条件变量等并发工具。AQS 维护了一个等待队列,用于存储等待获取同步状态的线程。当一个线程尝试获取同步状态失败时,它会被加入到等待队列中,等待其他线程释放同步状态。当一个线程释放同步状态时,AQS 会唤醒等待队列中的一个线程,使其有机会获取同步状态。

果酱 の 博客 1254

【NIPS 2022】时序精选论文07|Non-stationary Transformers: 引入非平稳性信息的平稳化序列预测模型(代码解读附源码)

整体代码框架基本上与传统 Transformer 类似,基本上只有在内嵌的注意力机制模块有区别,因此这里只对关键部分进行讲解,代码整体框架可参考 Transformer。非平稳时序很难预测,尤其对模型泛化性影响很大,试想下推理阶段的数据分布变了,模型很难适应这种变化。,比如很早以前的差分就是一种平稳化操作。序列平稳化能增强数据的可预测性,但这时也会带来一个问题,叫。,通过MLP层进行定义,使得参数可学习,以便于更好的融合到注意力网络中。代码中整体注意力的计算方式与原生Transformer类似,

ViolenceTemper的博客 1490

Java 并发编程之AQS

AbstractQueuedSynchronizer (AQS) 是 Java 并发编程中的一个核心框架,广泛用于构建锁和其他同步器(如信号量、读写锁等)。它是 java.util.concurrent.locks 包的一部分。AQS 的设计目的是简化并发同步器的实现。理解 AQS 对于深入理解 Java 并发编程非常重要。

微笑听雨 6762

Plecs电力电子仿真专业教程-第一季 第一节 Plecs简介

Plces 电力电子仿真专业教程系列依托专业的电力电子仿真软件Plecs对各种电力电子常用的拓扑及实际设计的方案进行系统及仿真与软件代码仿真实践。通过对各种电路仿真原理的讲解及专业C语言代码程序的编写,提升学员的系统设计能力,软件编程能力与理论分析能力。

3637

YOLOv26全流程实战手册:从yaml配置拆解到训练推理参数调优(附虚拟环境搭建)

以“车辆、行人、小型物体”3类数据集为例,修改# 1. 修改类别数nc: 3# 2. 调整锚框(适配小目标)anchors:- [12,16, 16,24, 33,23] # 增加小锚框# 3. 轻量化调整(边缘部署)depth_multiple: 0.25 # 降低深度系数width_multiple: 0.20 # 降低宽度系数# 其余Backbone/Head结构不变yaml配置:核心是调整nc(类别数)、(轻量化)、anchors(适配目标尺度);虚拟环境。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 877

并发编程 锁机制、线程池机制和AQS

Java并发编程是Java编程中非常重要的一部分,它允许开发者编写能够处理多个任务同时执行的应用程序。Java提供了一系列的工具和机制来支持并发编程,包括锁机制、线程池机制和AQS(AbstractQueuedSynchronizer)等。下面是对这些机制的总结: 锁机制 Java提供了多种锁机制来确保多线程之间的同步和互斥。 内置锁(synchronized): 是Java中最基本的锁机制。 可以用于方法或代码块。 可重入(Reentrant):一个线程可以多次获得同一个锁。 隐式锁获取和释放。

m0_61898915的博客 1331

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

AQS机制详解与总结

AQS(AbstractQueuedSynchronizer)机制详解与总结

qq_43857727的博客 2147

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Java并发编程,AQS详解

AQS是Java并发编程中一个不可或缺的工具,它不仅简化了锁的实现过程,还为开发者提供了一个强大的基础架构,使得我们可以轻松地创建各种类型的同步组件。理解AQS的工作原理及其相关的同步原语(如锁、条件变量等),可以帮助我们在编写复杂的并发程序时更加得心应手。需要注意的是,虽然AQS提供了许多便利的功能,但它仍然需要谨慎使用,尤其是在处理复杂的同步逻辑时。此外,随着Java版本的不断更新,越来越多的功能已经被标准化和封装到了更高级别的API中,因此我们应该优先考虑使用这些API来满足

横竖撇折点 2500

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

深入解析AQS原理:Java并发编程的核心

AQS(AbstractQueuedSynchronizer)是Java并发包()的核心组件,用于构建锁和其他同步器的基础框架。它通过一个FIFO队列管理线程的排队和唤醒机制,提供了独占模式和共享模式的同步功能。AQS的核心功能🧩同步状态管理:通过state变量管理锁的状态🛠️线程排队:通过FIFO队列管理等待线程🔒条件支持:支持条件变量(Condition)的实现AQS的应用Semaphore。

KBkongbaiKB的博客 1184

Java并发编程基石:深入解析AQS原理与应用实战

AQS(AbstractQueuedSynchronizer)是Java并发编程的核心框架,为构建锁和同步器提供基础设施。其核心包括同步状态(state)和CLH等待队列,支持独占和共享两种模式。独占模式如ReentrantLock实现线程互斥,共享模式如Semaphore允许多线程并发。AQS通过模板方法模式让子类定义资源获取/释放逻辑,提供公平与非公平策略选择。源码分析显示其通过CAS操作管理状态,队列机制实现高效线程调度。典型应用包括ReentrantLock、Semaphore等,开发者也可基于AQ

热爱技术、喜欢学习、乐于分享 1164

AQS核心原理分析《上》

本篇文章是关于并发编程中AQS的简介和组成知识记录,由于篇幅原因,独占模式和共享模式将会在下篇记录。

小威的博客 5722

Java并发编程核心:深入解析AQS

一文搞懂AQS

weixin_74047328的博客 925

Java并发编程深度解析:Condition条件变量的核心原理与实战应用

在并发编程的世界里,线程间的协调与通信是构建高性能、高可靠性系统的关键。传统的结合wait()notify()机制虽然简单易用,但在复杂的并发场景下却显得力不从心。当我们需要多个等待条件、精细的线程唤醒控制时,Java并发包中的Condition条件变量便应运而生,成为现代Java并发编程的重要利器。本文将深入剖析Condition的实现原理、使用模式、最佳实践,并结合实际案例展示其强大功能。条件变量(Condition)是。

用文字记录技术,用分享回馈社区,用坚持见证成长 1190

通过ReentrantLock掌握AQS的核心原理

通过ReentrantLock掌握AQS的核心原理

水w的博客 917

java并发编程 Atomic、CAS和AQS的介绍

/ 自定义信号量类 class CustomSemaphore {// 构造函数,初始化信号量许可数量 public CustomSemaphore(int permits) {} // 获取许可 public void acquire() throws InterruptedException {} // 释放许可 public void release() {

不知道说什么的博客 1100
上一篇: 开发避坑指南(56):IDEA2025.1.3新版本,这样配置工具栏,常用操作速度提升50%
下一篇: 开发避坑指南(57):Java Stream List转Map实战指南
帧栈
博客等级 码龄2年 335粉丝 120原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帧栈

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值