Apache Commons Pool :介绍与使用

Apache Commons Pool :介绍与使用

什么是 commons-pool2

commons-pool2 是 Apache Commons 提供的一个开源对象池实现框架。它旨在为应用程序提供通用的对象池支持,方便开发者管理资源(如数据库连接、网络连接等)复用,从而减少资源创建与销毁的开销,提高应用程序的性能和可扩展性。


功能特性

  1. 对象池管理:
    • 提供对象的创建、复用、回收、销毁机制。
  2. 多种池实现:
    • 支持通用对象池(GenericObjectPool)和键值对象池(GenericKeyedObjectPool)。
  3. 强大的配置支持:
    • 可以自定义池大小、最大闲置数、最小闲置数等。
  4. 线程安全:
    • 内部实现了高效的并发控制。
  5. 动态调节:
    • 支持在运行时动态调整池的大小和行为。

如何使用

Maven 依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.11.1</version>
</dependency>

使用步骤

  1. 创建对象工厂:
    • 实现 org.apache.commons.pool2.PooledObjectFactory 接口,用于定义对象的创建和销毁逻辑。
  2. 初始化对象池:
    • 使用 GenericObjectPoolGenericKeyedObjectPool 来管理对象池。
  3. 获取与归还对象:
    • 使用 borrowObject() 从池中获取对象,用完后通过 returnObject() 将对象归还到池中。

示例:使用 GenericObjectPool

以下是一个简单的数据库连接池实现。

import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

// 模拟的数据库连接类
class DatabaseConnection {
    private String id;

    public DatabaseConnection(String id) {
        this.id = id;
    }

    public void connect() {
        System.out.println("Connecting to database with ID: " + id);
    }

    public void close() {
        System.out.println("Closing database connection with ID: " + id);
    }

    public String getId() {
        return id;
    }
}

// 数据库连接工厂类
class DatabaseConnectionFactory implements PooledObjectFactory<DatabaseConnection> {
    private int counter = 0;

    @Override
    public PooledObject<DatabaseConnection> makeObject() {
        DatabaseConnection connection = new DatabaseConnection("DB-" + (++counter));
        System.out.println("Creating new connection: " + connection.getId());
        return new DefaultPooledObject<>(connection);
    }

    @Override
    public void destroyObject(PooledObject<DatabaseConnection> p) {
        p.getObject().close();
    }

    @Override
    public boolean validateObject(PooledObject<DatabaseConnection> p) {
        return true; // 假设所有对象都有效
    }

    @Override
    public void activateObject(PooledObject<DatabaseConnection> p) {
        p.getObject().connect();
    }

    @Override
    public void passivateObject(PooledObject<DatabaseConnection> p) {
        // 暂时不需要实现
    }
}

public class ConnectionPoolExample {
    public static void main(String[] args) throws Exception {
        // 配置对象池
        GenericObjectPoolConfig<DatabaseConnection> config = new GenericObjectPoolConfig<>();
        config.setMaxTotal(5);          // 最大对象数
        config.setMaxIdle(3);           // 最大闲置数
        config.setMinIdle(1);           // 最小闲置数
        config.setTestOnBorrow(true);   // 借出时测试对象是否有效

        // 创建对象池
        GenericObjectPool<DatabaseConnection> pool = new GenericObjectPool<>(new DatabaseConnectionFactory(), config);

        // 使用对象池
        DatabaseConnection conn1 = pool.borrowObject(); // 从池中获取对象
        conn1.connect();

        DatabaseConnection conn2 = pool.borrowObject();
        conn2.connect();

        pool.returnObject(conn1); // 将对象归还到池中
        pool.returnObject(conn2);

        // 销毁池
        pool.close();
    }
}

输出示例

Creating new connection: DB-1
Connecting to database with ID: DB-1
Connecting to database with ID: DB-2
Closing database connection with ID: DB-1
Closing database connection with ID: DB-2

优化方式

  1. 合理配置池参数:

    • maxTotal:限制最大对象数,防止过多对象占用内存。
    • minIdle:设置最小闲置数,避免频繁创建与销毁对象。
    • maxWaitMillis:设置获取对象的超时时间。
  2. 定期测试池对象:

    • setTestOnBorrow(true):借出时验证对象。
    • setTestOnReturn(true):归还时验证对象。
    • setTestWhileIdle(true):闲置时验证对象。
  3. 监控池性能:

    • 利用池的 getNumActive()getNumIdle() 方法动态监控池中活动与闲置的对象数。
  4. 资源回收:

    • 确保池在不需要时调用 close() 释放资源。

常见场景

  1. 数据库连接池
  2. 网络连接池
  3. 线程池管理
  4. 文件句柄池

commons-pool2 闲置对象过期及设置详解

默认行为

commons-pool2 的连接池实现中,闲置对象的过期时间以及移除行为由多个参数共同决定。

默认配置

  • 默认情况下,如果没有显式设置移除闲置对象的策略,连接池中的对象可能因为资源限制而被移除。
  • 具体的移除时机依赖于如下参数设置。

相关参数详解

1. minIdle

  • 描述: 最小闲置连接数。
  • 作用: 保证连接池中始终有一定数量的对象处于闲置状态。
  • 默认值: 0(即没有保留最小闲置对象)。
  • 影响: 如果设置为较大的值,连接池会在对象被移除前尝试补充更多的空闲对象。

2. timeBetweenEvictionRunsMillis

  • 描述: 间隔多久运行一次空闲对象的逐出检查线程(以毫秒为单位)。
  • 默认值: -1(表示不运行逐出线程)。
  • 建议优化: 设置为合理的时间间隔,例如 30000 毫秒(30 秒)。

3. minEvictableIdleTimeMillis

  • 描述: 对象在池中保持空闲状态的最小时间(以毫秒为单位),超过该时间的对象可能会被移除。
  • 默认值: 1800000 毫秒(30 分钟)。
  • 建议优化: 设置为较小的值以快速移除闲置对象,例如 600000 毫秒(10 分钟)。

4. softMinEvictableIdleTimeMillis

  • 描述: 对象在池中保持空闲状态的最小时间(以毫秒为单位),但只有当空闲对象超过 minIdle 时才会被移除。
  • 默认值: 未设置。
  • 建议优化: 配合 minIdle 使用,用于延长部分闲置对象的存活时间。

5. numTestsPerEvictionRun

  • 描述: 每次空闲对象检查时检测的对象数量。
  • 默认值: -1(检查所有对象)。
  • 建议优化: 根据池的大小设置为一个合理的值,例如 10

配置示例

以下是一个完整的连接池配置示例:

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class PoolConfigExample {
    public static void main(String[] args) {
        GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>();

        // 设置最小空闲对象数
        config.setMinIdle(5);

        // 设置最大空闲对象数
        config.setMaxIdle(20);

        // 设置最大池容量
        config.setMaxTotal(50);

        // 设置空闲对象逐出线程运行间隔(30 秒)
        config.setTimeBetweenEvictionRunsMillis(30000);

        // 设置空闲对象的最小逐出时间(10 分钟)
        config.setMinEvictableIdleTimeMillis(600000);

        // 检查空闲对象的线程一次处理的数量
        config.setNumTestsPerEvictionRun(5);

        // 创建连接池
        GenericObjectPool<Object> pool = new GenericObjectPool<>(new MyObjectFactory(), config);

        System.out.println("连接池初始化完成!");
    }
}

// 示例对象工厂
class MyObjectFactory extends BasePooledObjectFactory<Object> {
    @Override
    public Object create() throws Exception {
        return new Object(); // 返回一个新对象
    }

    @Override
    public PooledObject<Object> wrap(Object obj) {
        return new DefaultPooledObject<>(obj);
    }
}

总结

空闲对象的移除策略

  • 默认情况下,闲置对象不会自动过期,除非设置了逐出线程参数(如 timeBetweenEvictionRunsMillis)。
  • 设置 minEvictableIdleTimeMillis 可以明确指定闲置对象的过期时间。
  • 通过调优 minIdlemaxIdle 可以更好地控制池中对象的生命周期。

推荐配置

  • 动态调整参数: 根据实际负载和资源需求动态调整 minIdletimeBetweenEvictionRunsMillis
  • 观察性能: 通过性能测试和监控,逐步优化连接池的行为,减少过期对象对系统性能的影响。

Apache Commons Pool: 最小闲置数与逐出线程的交互行为

背景介绍

Apache Commons Pool 是一个高效的对象池管理库,广泛用于连接池、线程池等需要管理资源的场景。其配置包括 最小闲置数 (minIdle)逐出线程 (Evictor) 参数。

  • 最小闲置数 (minIdle)

    • 定义对象池中需要保持的最小空闲对象数。
    • 如果空闲对象少于该值,池会创建新的对象,直到满足 minIdle
  • 逐出线程 (Evictor)

    • 周期性检查并清理空闲对象。
    • timeBetweenEvictionRunsMillisminEvictableIdleTimeMillis 参数控制。

参数交互行为

minIdle 和逐出线程参数同时设置时,逐出线程会考虑 minIdle,确保空闲对象数不低于该值。

逐出线程行为规则

  1. 逐出线程运行规则

    • 定期检查空闲对象是否超过 minEvictableIdleTimeMillis
    • 清理超过空闲时间的对象。
  2. 空闲对象保留规则

    • 如果当前空闲对象数少于或等于 minIdle,逐出线程不会清理这些对象。
    • 若空闲对象数大于 minIdle,逐出线程会清理部分对象,直到空闲对象数等于 minIdle 或更少。

参数对行为的影响

参数描述
minIdle池中最小保留空闲对象数。
timeBetweenEvictionRunsMillis逐出线程运行的时间间隔(毫秒)。
minEvictableIdleTimeMillis对象可被清理的最小空闲时间(毫秒)。

示例代码

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class PoolConfigExample {
    public static void main(String[] args) {
        GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>();
        
        // 设置最小空闲数
        config.setMinIdle(5);
        
        // 逐出线程每30秒运行一次
        config.setTimeBetweenEvictionRunsMillis(30000);
        
        // 空闲时间超过60秒的对象可能被清理
        config.setMinEvictableIdleTimeMillis(60000);
        
        // 示例:确保至少保留5个空闲对象
        System.out.println("Pool configured with minIdle=5");
    }
}

特殊场景

  1. 最小闲置数未设置或为0

    • 空闲对象数可能会被清理为 0。
    • 下次获取对象时需要重新创建,可能导致性能下降。
  2. 逐出线程未设置

    • 空闲对象永远不会被清理,可能造成内存占用。

重要结论

  • 逐出线程不会清理到低于 minIdle 的空闲对象数
  • 如果设置合理的 minEvictableIdleTimeMillistimeBetweenEvictionRunsMillis,可以在资源回收与性能间取得平衡。
  • 配置建议:
    • 保证 minIdle 的值与系统负载需求匹配。
    • 根据对象的生命周期合理配置 minEvictableIdleTimeMillis
    • 避免过于频繁或过于稀疏的逐出线程运行时间。

总结

Apache Commons Pool 提供了灵活的参数配置,支持多种资源池管理场景。当 minIdle 和逐出线程参数同时设置时,系统会优先保证 minIdle 的空闲对象数,不会因逐出线程清理而导致空闲对象不足。合理的参数配置可以在资源利用率与性能间找到最佳平衡点。


Apache Commons Pool - 逐出线程设置指南

背景

在使用 Apache Commons Pool 进行对象池管理时,如果未设置逐出线程,空闲对象将永远不会被清理,可能导致内存占用问题。因此,合理配置逐出线程的相关参数可以避免资源泄露,提高系统性能。


关键参数

timeBetweenEvictionRunsMillis

  • 作用:控制逐出线程的运行周期(以毫秒为单位)。
  • 默认值-1,表示逐出线程不运行。
  • 建议设置:例如 60000 表示每分钟运行一次。

minEvictableIdleTimeMillis

  • 作用:设置空闲对象被逐出的最小生存时间(以毫秒为单位)。
  • 默认值1800000(30 分钟)。
  • 建议设置:根据业务需求调整,例如 10 分钟:600000

minIdle

  • 作用:确保池中始终保持的最小空闲对象数。即使逐出线程运行,也不会清理低于该数量的空闲对象。
  • 建议设置:根据系统负载调整,例如 5

maxIdle

  • 作用:限制池中空闲对象的最大数量。如果空闲对象超过此值,多余的对象会被逐出。
  • 建议设置:例如 10

配置代码示例

以下代码展示如何通过 GenericObjectPool 设置逐出线程:

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class PoolExample {
    public static void main(String[] args) {
        // 配置池参数
        GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>();

        // 设置最小空闲连接数
        config.setMinIdle(5);

        // 设置最大空闲连接数
        config.setMaxIdle(10);

        // 设置最大连接数
        config.setMaxTotal(20);

        // 逐出线程运行周期(每 60 秒运行一次)
        config.setTimeBetweenEvictionRunsMillis(60000);

        // 最小可逐出时间(30 分钟未使用的空闲对象会被清理)
        config.setMinEvictableIdleTimeMillis(1800000);

        // 创建对象池
        GenericObjectPool<Object> pool = new GenericObjectPool<>(new ObjectFactory(), config);

        // 使用对象池
        try {
            Object obj = pool.borrowObject(); // 获取对象
            pool.returnObject(obj);           // 归还对象
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            pool.close(); // 关闭池
        }
    }

    // 自定义对象工厂
    static class ObjectFactory extends BasePooledObjectFactory<Object> {
        @Override
        public Object create() {
            return new Object(); // 创建对象
        }

        @Override
        public PooledObject<Object> wrap(Object obj) {
            return new DefaultPooledObject<>(obj); // 包装对象
        }
    }
}

参数详细说明

参数名称作用示例值
setTimeBetweenEvictionRunsMillis控制逐出线程的运行周期。正值表示启用逐出线程,例如 60000 表示每分钟运行一次。60000
setMinEvictableIdleTimeMillis空闲对象的最小生存时间,超过此时间的对象会被逐出。1800000
setMinIdle保证的最小空闲对象数,即使逐出线程运行,也不会清理低于该数量的对象。5
setMaxIdle最大空闲对象数,超过此值的对象会被逐出。10

配置文件示例

可以通过 properties 文件加载配置:

pool.minIdle=5
pool.maxIdle=10
pool.maxTotal=20
pool.timeBetweenEvictionRunsMillis=60000
pool.minEvictableIdleTimeMillis=1800000

在代码中加载配置:

Properties props = new Properties();
try (InputStream input = new FileInputStream("config.properties")) {
    props.load(input);
    GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>();
    config.setMinIdle(Integer.parseInt(props.getProperty("pool.minIdle")));
    config.setMaxIdle(Integer.parseInt(props.getProperty("pool.maxIdle")));
    config.setMaxTotal(Integer.parseInt(props.getProperty("pool.maxTotal")));
    config.setTimeBetweenEvictionRunsMillis(Long.parseLong(props.getProperty("pool.timeBetweenEvictionRunsMillis")));
    config.setMinEvictableIdleTimeMillis(Long.parseLong(props.getProperty("pool.minEvictableIdleTimeMillis")));
}

优化建议

  1. 合理设置最小和最大空闲对象数:避免频繁创建和销毁对象。
  2. 监控池性能:通过池提供的指标(例如活动对象数、空闲对象数)动态调整配置。
  3. 避免逐出线程频繁运行:将逐出线程运行周期设置为合理的值,例如 1 分钟或更长时间。
  4. 测试与调优:根据实际使用场景不断调整参数,平衡性能与资源消耗。

通过合理设置逐出线程和相关参数,可以显著提高对象池的性能和资源利用效率。


线程数量逐渐增加的原因分析与参数设置建议

当线程数量逐渐增加时,可能是由于以下原因或参数设置的问题导致的。以下是详细分析及解决方法。


1. 未限制线程池最大线程数量

  • 原因

    • 未设置线程池的最大线程数 (maxTotal),默认值可能非常大甚至是无界的。随着任务增加,线程池不断创建新线程来满足请求,导致线程数量逐渐增加。
  • 解决方法

    • 设置合理的 maxTotal 值,以限制线程池中的最大线程数。

2. 核心线程数设置过高

  • 原因

    • corePoolSize 是线程池中核心线程的数量。如果设置过高,即使任务较少,线程池也会保持较多的核心线程。
  • 解决方法

    • 根据实际需求,设置一个合理的 corePoolSize 值,以减少空闲线程的数量。

3. 空闲线程未被回收

  • 原因

    • 空闲线程的生存时间参数 (minEvictableIdleTimeMillis) 过长,导致空闲线程无法及时被逐出。
  • 解决方法

    • 设置 minEvictableIdleTimeMillis 为合理的时间(如 30 秒或 60 秒),使得空闲线程能在闲置一段时间后被回收。

4. 逐出线程未启动

  • 原因

    • 未启用逐出线程(Evictor),导致空闲线程不会被定期清理,线程池中的线程数量可能持续累积。
  • 解决方法

    • 设置 timeBetweenEvictionRunsMillis 为一个正值(如 30000 毫秒),开启逐出线程。
    • 配合使用 minEvictableIdleTimeMillisnumTestsPerEvictionRun 参数进行逐出策略优化。

5. 任务积压导致线程池扩容

  • 原因

    • 线程池的队列(workQueue)容量不足时,新任务可能会触发线程池动态扩容。如果任务积压过多,线程池可能创建更多线程来处理任务。
  • 解决方法

    • 使用有限大小的阻塞队列(如 LinkedBlockingQueue),并合理设置其容量。
    • 设置 maximumPoolSize 限制线程数量的扩展。

6. 线程工厂问题

  • 原因

    • 如果线程池使用的 ThreadFactory 未正确管理线程,可能会导致线程池创建更多的线程。
  • 解决方法

    • 确保 ThreadFactory 正确实现,并为线程池创建的线程设置合理的优先级、命名和守护线程属性。

7. 线程泄漏

  • 原因

    • 某些任务未正常退出线程,或线程被错误地持久化,导致线程池中的线程无法被回收。
  • 解决方法

    • 定期监控线程池中的活动线程数。
    • 确保任务逻辑正确,避免线程长期处于阻塞状态。

参数设置示例

以下是一个合理的线程池参数设置,避免线程数量逐渐增加:

GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>();
config.setMaxTotal(100); // 设置线程池最大线程数
config.setMinIdle(10);  // 设置最小闲置线程数
config.setMaxIdle(50);  // 设置最大闲置线程数
config.setTimeBetweenEvictionRunsMillis(30000); // 逐出线程运行间隔
config.setMinEvictableIdleTimeMillis(60000);   // 最小闲置时间
config.setNumTestsPerEvictionRun(3);           // 每次逐出线程检测的对象数

通过合理的参数设置,可以有效控制线程数量,避免不必要的资源消耗。


对象清理行为分析及配置

问题描述

最小闲置数未设置或为0逐出线程未设置 的情况下,如何清理空闲对象?是优先清理最小闲置数为0的对象,还是优先考虑逐出线程未设置的情况,即使最小闲置数为0也不清理?


行为规则分析

1. 最小闲置数未设置或为0

  • 效果
    • 如果 minIdle 设置为 0 或未设置,则空闲池对象可以降到 0 个,即没有任何最小保留的连接或线程。
    • 但仅此设置并不会直接导致清理,因为清理动作需要逐出线程的参与。

2. 逐出线程未设置

  • 效果
    • 如果没有设置逐出线程(即未配置 evictor),则系统不会主动清理空闲对象。
    • 即使 minIdle0,由于缺少逐出线程触发,空闲对象仍然会长期存在。

3. 优先顺序

  • 逐出线程优先控制清理逻辑:如果没有逐出线程,即使 minIdle0,也不会清理空闲对象。
  • 清理动作需要逐出线程定期检查并触发。

总结行为

1. 逐出线程未设置的情况

  • 空闲对象永远不会被清理。
  • 即使 minIdle0,对象也会一直存在,导致资源可能被长期占用。

2. 逐出线程设置了,但 minIdle 为0的情况

  • 逐出线程会按照配置定期运行,清理空闲对象,直到池中对象数量为 0

优化建议

1. 如果希望空闲对象及时释放:

  • 配置逐出线程参数:
    • timeBetweenEvictionRunsMillis:逐出线程运行的时间间隔(单位:毫秒)。
    • minEvictableIdleTimeMillis:空闲对象被逐出的最短存活时间(单位:毫秒)。
  • 设置 minIdle 为合适的非零值(如 minIdle = 2),确保资源池中保留一定数量的空闲对象。

2. 如果不希望清理空闲对象:

  • 设置 minIdle 为大于 0 的值(如 minIdle = 5)。
  • 不设置逐出线程参数,或将 timeBetweenEvictionRunsMillis 设置为一个较大的值,避免频繁触发清理。

示例代码

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();

// 设置最小闲置数为 0
config.setMinIdle(0);

// 配置逐出线程,每 30 秒运行一次
config.setTimeBetweenEvictionRunsMillis(30000);

// 空闲对象超过 60 秒被逐出
config.setMinEvictableIdleTimeMillis(60000);

参数含义

参数名说明示例值
minIdle最小闲置对象数0
timeBetweenEvictionRunsMillis逐出线程运行间隔30000
minEvictableIdleTimeMillis空闲对象存活时间60000

通过合理的配置,可以有效管理资源池对象的生命周期,防止资源浪费或内存泄漏,同时提升系统性能。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/945956.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

编辑音频的基本属性

导入音频 “文件-导入-选择音频”拖到音频轨道创建序列。选择音频&#xff0c;在效果空间可以看到音频的基本属性。 音量的设置 “效果工作区-效果控件-音量”在这里可以控制所有引导的混合音量 静音 静止所有声音 音频仪表 一般位于时间轴的后面&#xff0c;找不到可以…

SQL 基础教程 - SQL SELECT 语句

SQL SELECT DISTINCT 语句 SELECT DISTINCT 语句用于返回唯一不同的值。 在表中&#xff0c;一个列可能会包含多个重复值&#xff0c;有时您也许希望仅仅列出不同&#xff08;distinct&#xff09;的值。 DISTINCT 关键词用于返回唯一不同的值。 SQL SELECT DISTINCT 语法 …

Oracle 回归分析函数使用

Oracle 回归分析函数使用 文章目录 Oracle 回归分析函数使用什么是 回归分析函数回归分析函数示例1. 分析 SAL 和 COMM 之间的回归关系2. 按部门分析 SAL 和 COMM 的关系3. 根据 SAL 预测 COMM4. 分析员工薪资与工作年限的关5. 按部门分析工作年限与薪资的关系6. 计算 REGR_AVG…

idea项目导入gitee 码云

1、安装gitee插件 IDEA 码云插件已由 gitosc 更名为 gitee。 1 在码云平台帮助文档http://git.mydoc.io/?t153739上介绍的很清楚&#xff0c;推荐前两种方法&#xff0c; 搜索码云插件的时候记得名字是gitee&#xff0c;gitosc已经搜不到了。 2、使用码云托管项目 如果之…

Cesium 实战 27 - 三维视频融合(视频投影)

Cesium 实战 27 - 三维视频融合(视频投影) 核心代码完整代码在线示例在 Cesium 中有几种展示视频的方式,比如墙体使用视频材质,还有地面多边形使用视频材质,都可以实现视频功能。 但是随着摄像头和无人机的流行,需要视频和场景深度融合,简单的实现方式则不能满足需求。…

spring boot的各个版本介绍

Spring Boot 是一个用于创建独立、生产级别的基于 Spring 的应用程序的框架。自2014年首次发布以来&#xff0c;Spring Boot 经历了多个版本的迭代&#xff0c;每个版本都带来了新特性、性能改进和错误修复。下面是对Spring Boot一些主要版本的简要介绍&#xff1a; Spring Boo…

基于zynq在linux下的HDMI实战

ZYNQ系列文章目录 第一章&#xff1a;基于zynq在linux下的phy调试记录 第二章&#xff1a;qemu制作ubuntu文件系统 第三章&#xff1a;基于zynq在linux下的AXI-CAN实战 第四章&#xff1a;基于zynq在linux下的HDMI实战 文章目录 ZYNQ系列文章目录前言一、vivado中HDMI的配置1.…

LabVIEW 实现自动对焦的开发

自动对焦&#xff08;Autofocus, AF&#xff09;技术是通过分析图像或传感器信号&#xff0c;动态调整焦点位置以实现清晰成像或高精度定位的过程。在LabVIEW中&#xff0c;可以通过集成信号采集、数据处理、控制算法和硬件接口模块&#xff0c;实现多种自动对焦方法&#xff0…

机器人C++开源库The Robotics Library (RL)使用手册(四)

建立自己的机器人3D模型和运动学模型 这里以国产机器人天机TR8为例,使用最普遍的DH运动学模型,结合RL所需的描述文件,进行生成。 最终,需要的有两个文件,一个是.wrl三维模型描述文件;一个是.xml运动学模型描述文件。 1、通过STEP/STP三维文件生成wrl三维文件 机器人的…

直播电商系统源码搭建实战:快速开发多商户带货APP的指南

今天&#xff0c;笔者将从源码选择、功能设计、开发流程等方面&#xff0c;带你了解如何快速开发一个高效实用的直播电商系统。 一、明确需求&#xff1a;功能设计是基础 以下是一个多商户直播电商系统的核心功能模块&#xff1a; -商户管理模块 -直播带货模块 -商品管理模…

风力涡轮机缺陷检测数据集,86.6%准确识别率,11921张图片,支持yolo,PASICAL VOC XML,COCO JSON格式的标注

风力涡轮机缺陷检测数据集&#xff0c;86.6&#xff05;准确识别率&#xff0c;11921张图片&#xff0c;支持yolo&#xff0c;PASICAL VOC XML&#xff0c;COCO JSON格式的标注 数据集下载 yolov11&#xff1a; https://download.csdn.net/download/pbymw8iwm/90206849 yolov…

委外加工业务如何调整原材料的消耗-MIGO A11-后续调整

业务背景&#xff1a;用户反馈委外加工业务回收后&#xff0c;产品已经销售&#xff0c;但委外加工结算时要对原材料消耗时行调整。如果没有销售&#xff0c;准备采用收货冲销后重新收货&#xff0c;但现在已经是2024年最后一天了。。。销售业务已经做完。不可能再冲销。其实这…

ultralytics库RT-DETR代码解析

最近读了maskformer以及maskdino的分割头设计&#xff0c;于是想在RT-DETR上做一个分割的改动&#xff0c;所以选择在ultralytics库中对RTDETR进行改进。 本文内容简介&#xff1a; 1.ultralytics库中RT-DETR模型解析 2. 对ultralytics库中的RT-DETR模型增加分割头做实例分割 …

25. C++继承 1 (继承的概念与基础使用, 继承的复制兼容规则,继承的作用域)

⭐上篇模板文章&#xff1a;24. C模板 2 (非类型模板参数&#xff0c;模板的特化与模板的分离编译)-CSDN博客 ⭐本篇代码&#xff1a;c学习 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) ⭐标⭐是比较重要的部分 目录 一. 继承的基础使用 1.1 继承的格式 1.2 …

宽带、光猫、路由器、WiFi、光纤之间的关系

1、宽带&#xff08;Broadband&#xff09; 1.1 宽带的定义宽带指的是一种高速互联网接入技术&#xff0c;通常包括ADSL、光纤、4G/5G等不同类型的接入方式。宽带的关键特点是能够提供较高的数据传输速率&#xff0c;使得用户可以享受到稳定的上网体验。 1.2 宽带的作用宽带是…

【AndroidAPP】权限被拒绝:[android.permission.READ_EXTERNAL_STORAGE],USB设备访问权限系统报错

一、问题原因 1.安卓安全性变更 Android 12 的安全性变更&#xff0c;Google 引入了更严格的 PendingIntent 安全管理&#xff0c;强制要求开发者明确指定 PendingIntent 的可变性&#xff08;Mutable&#xff09;或不可变性&#xff08;Immutable&#xff09;。 但是&#xf…

Inno Setup生成exe安装包

Inno Setup生成exe安装包 第一步&#xff1a;创建一个带向导的脚本文件 第二步&#xff1a;直接 Next&#xff0c;不要创建空的脚本文件 第三步&#xff1a;填写相关的应用程序信息 第四步&#xff1a;指定应用程序的安装目录相关的信息 第五步&#xff1a;选择可执行程序和相…

数据库MHA

MHA 什么是MHA -------- MASTER HIGH AVAILABILITY 建立在主从复制基础之上的故障切换到软件系统 主从复制的单点问题&#xff1a; 当主从复制当中&#xff0c;主服务器发生故障&#xff0c;会自动切换到一台从服务器&#xff0c;然后把从服务器升格为主&#xff0c;继续主…

vue2 - Day04 - 插槽、路由

插槽、路由 一、插槽&#xff08;solt&#xff09;1.1 概念1.2 基本用法1.3 分类1.3.1 默认插槽&#xff08;Default Slot&#xff09;例子&#xff1a; 1.3.2 具名插槽&#xff08;Named Slots&#xff09;语法&#xff1a; 1.3.3 作用域插槽&#xff08;Scoped Slots&#xf…

微信小程序:定义页面标题,动态设置页面标题,json

1、常规设置页面标题 正常微信小程序中&#xff0c;设置页面标题再json页面中进行设置&#xff0c;例如 {"usingComponents": {},"navigationBarTitleText": "标题","navigationBarBackgroundColor": "#78b7f7","navi…