Java线程池深度解析:从原理到实战的完整指南

在这里插入图片描述

Java线程池深度解析:从原理到实战的完整指南

🌟 你好,我是 励志成为糕手 !
🌌 在代码的宇宙中,我是那个追逐优雅与性能的星际旅人。 ✨
每一行代码都是我种下的星光,在逻辑的土壤里生长成璀璨的银河;
🛠️ 每一个算法都是我绘制的星图,指引着数据流动的最短路径; 🔍
每一次调试都是星际对话,用耐心和智慧解开宇宙的谜题。
🚀 准备好开始我们的星际编码之旅了吗?

目录

  • Java线程池深度解析:从原理到实战的完整指南
    • 摘要
    • 1. 线程池基础概念
      • 1.1 什么是线程池
      • 1.2 线程池的优势
    • 2. ThreadPoolExecutor核心原理
      • 2.1 核心参数详解
      • 2.2 线程池执行流程
      • 2.3 工作队列类型对比
    • 3. 常用线程池类型
      • 3.1 Executors工厂方法
      • 3.2 线程池选择决策图
    • 4. 拒绝策略与异常处理
      • 4.1 四种内置拒绝策略
      • 4.2 拒绝策略对比分析
    • 5. 线程池监控与调优
      • 5.1 监控指标与实现
      • 5.2 性能调优策略
    • 6. 实战案例:Web服务线程池优化
      • 6.1 问题场景与解决方案
      • 6.2 系统架构图
    • 总结
    • 参考链接
    • 关键词标签

摘要

大家好,我是励志成为糕手!今天我要和大家深入探讨Java并发编程中的核心组件——线程池。在我多年的开发经验中,线程池可以说是提升应用性能的利器,也是面试中的高频考点。

线程池的本质是对线程资源的统一管理和复用。想象一下,如果每次需要执行任务都创建新线程,就像每次出门都要重新造车一样低效。线程池就是我们的"车库",里面停放着预先创建好的线程"车辆",需要时直接取用,用完归还,大大提升了资源利用效率。

在实际项目中,我曾遇到过因为线程创建过多导致的内存溢出问题,也见过因为线程池配置不当引发的性能瓶颈。通过合理使用线程池,不仅能够控制系统资源消耗,还能提供更好的任务管理能力,包括任务排队、优先级处理、异常处理等。

本文将从线程池的基本概念出发,深入分析其核心原理,包括ThreadPoolExecutor的工作机制、核心参数配置、拒绝策略等。同时,我会结合实际案例,展示不同场景下的线程池选择和优化策略,帮助大家在实际开发中游刃有余地运用这一强大工具。

1. 线程池基础概念

1.1 什么是线程池

线程池是一种多线程处理形式,它预先创建若干个线程,这些线程在没有任务处理时处于等待状态,当有任务来临时从线程池中取出一个空闲线程来处理任务,处理完之后线程不会销毁,而是返回线程池继续等待处理其他任务。

// 基本的线程池创建示例
public class BasicThreadPoolExample {public static void main(String[] args) {// 创建固定大小的线程池ExecutorService executor = Executors.newFixedThreadPool(5);// 提交任务for (int i = 0; i < 10; i++) {final int taskId = i;executor.submit(() -> {System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());try {Thread.sleep(2000); // 模拟任务执行} catch (InterruptedException e) {Thread.currentThread().interrupt();}});}// 关闭线程池executor.shutdown();}
}

这个示例展示了线程池的基本使用:创建固定大小的线程池,提交多个任务,最后关闭线程池。关键点在于线程的复用和任务的排队机制。

1.2 线程池的优势

线程池优势
资源控制
性能提升
管理便利
响应速度
限制线程数量
避免资源耗尽
内存管理优化
线程复用
减少创建销毁开销
提高吞吐量
统一任务管理
监控和调试
异常处理
预创建线程
快速任务分配
减少等待时间

图1:线程池优势架构图 - 展示线程池在资源控制、性能提升等方面的核心优势

2. ThreadPoolExecutor核心原理

2.1 核心参数详解

ThreadPoolExecutor是Java线程池的核心实现类,理解其构造参数是掌握线程池的关键:

public class ThreadPoolParameters {public static void main(String[] args) {ThreadPoolExecutor executor = new ThreadPoolExecutor(2,                      // corePoolSize: 核心线程数5,                      // maximumPoolSize: 最大线程数60L,                    // keepAliveTime: 空闲线程存活时间TimeUnit.SECONDS,       // unit: 时间单位new LinkedBlockingQueue<>(10),  // workQueue: 工作队列new ThreadFactory() {   // threadFactory: 线程工厂private AtomicInteger counter = new AtomicInteger(0);@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r, "CustomThread-" + counter.incrementAndGet());t.setDaemon(false);return t;}},new ThreadPoolExecutor.CallerRunsPolicy()  // handler: 拒绝策略);// 监控线程池状态monitorThreadPool(executor);executor.shutdown();}private static void monitorThreadPool(ThreadPoolExecutor executor) {System.out.println("Core Pool Size: " + executor.getCorePoolSize());System.out.println("Maximum Pool Size: " + executor.getMaximumPoolSize());System.out.println("Current Pool Size: " + executor.getPoolSize());System.out.println("Active Count: " + executor.getActiveCount());System.out.println("Queue Size: " + executor.getQueue().size());}
}

这段代码展示了ThreadPoolExecutor的完整构造过程,每个参数都有其特定作用,合理配置这些参数是线程池性能优化的基础。

2.2 线程池执行流程

客户端线程池核心线程工作队列最大线程拒绝处理器提交任务创建核心线程执行任务完成任务入队入队成功获取任务执行创建非核心线程执行任务触发拒绝策略处理拒绝alt[未达最大线程数][达到最大线程数]alt[队列未满][队列已满]alt[核心线程未满][核心线程已满]客户端线程池核心线程工作队列最大线程拒绝处理器

图2:线程池任务执行时序图 - 展示任务从提交到执行的完整流程

2.3 工作队列类型对比

队列类型特点适用场景容量限制性能特征
ArrayBlockingQueue有界阻塞队列资源受限环境固定容量高并发性能好
LinkedBlockingQueue可选有界队列一般业务场景可配置吞吐量高
SynchronousQueue直接传递快速响应场景0延迟最低
PriorityBlockingQueue优先级队列任务有优先级无界支持排序
DelayQueue延迟队列定时任务无界支持延迟执行

3. 常用线程池类型

3.1 Executors工厂方法

public class ExecutorsExample {public static void demonstrateExecutors() {// 1. 固定线程池 - 适用于负载较重的服务器ExecutorService fixedPool = Executors.newFixedThreadPool(4);// 2. 缓存线程池 - 适用于执行很多短期异步任务ExecutorService cachedPool = Executors.newCachedThreadPool();// 3. 单线程池 - 适用于需要保证顺序执行的场景ExecutorService singlePool = Executors.newSingleThreadExecutor();// 4. 定时线程池 - 适用于定时及周期性任务执行ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(2);// 使用示例testFixedThreadPool(fixedPool);testScheduledThreadPool(scheduledPool);// 关闭所有线程池shutdownPools(fixedPool, cachedPool, singlePool, scheduledPool);}private static void testFixedThreadPool(ExecutorService executor) {System.out.println("=== 固定线程池测试 ===");for (int i = 0; i < 8; i++) {final int taskId = i;executor.submit(() -> {System.out.printf("Fixed Pool - Task %d executed by %s%n", taskId, Thread.currentThread().getName());simulateWork(1000);});}}private static void testScheduledThreadPool(ScheduledExecutorService executor) {System.out.println("=== 定时线程池测试 ===");// 延迟执行executor.schedule(() -> {System.out.println("延迟任务执行: " + new Date());}, 2, TimeUnit.SECONDS);// 周期性执行executor.scheduleAtFixedRate(() -> {System.out.println("周期任务执行: " + new Date());}, 1, 3, TimeUnit.SECONDS);}private static void simulateWork(long millis) {try {Thread.sleep(millis);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}private static void shutdownPools(ExecutorService... pools) {for (ExecutorService pool : pools) {pool.shutdown();}}
}

这个示例展示了不同类型线程池的创建和使用场景,每种线程池都有其特定的适用场景和性能特征。

3.2 线程池选择决策图

短时间
长时间
高频
低频
高频
低频
任务特征分析
任务执行时间
任务频率
任务频率
CachedThreadPool
快速响应短任务
SingleThreadExecutor
简单顺序执行
FixedThreadPool
稳定处理长任务
ScheduledThreadPool
定时任务处理
特殊需求
CustomThreadPool
自定义配置

图3:线程池选择象限图 - 根据任务特征选择合适的线程池类型

4. 拒绝策略与异常处理

4.1 四种内置拒绝策略

public class RejectionPolicyDemo {public static void demonstrateRejectionPolicies() {// 1. AbortPolicy - 抛出异常(默认)testAbortPolicy();// 2. CallerRunsPolicy - 调用者执行testCallerRunsPolicy();// 3. DiscardPolicy - 静默丢弃testDiscardPolicy();// 4. DiscardOldestPolicy - 丢弃最老任务testDiscardOldestPolicy();// 5. 自定义拒绝策略testCustomRejectionPolicy();}private static void testAbortPolicy() {ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(1),new ThreadPoolExecutor.AbortPolicy());try {// 提交超过容量的任务for (int i = 0; i < 5; i++) {executor.submit(() -> {try { Thread.sleep(1000); } catch (InterruptedException e) {}});}} catch (RejectedExecutionException e) {System.out.println("AbortPolicy: 任务被拒绝 - " + e.getMessage());} finally {executor.shutdown();}}private static void testCallerRunsPolicy() {ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(1),new ThreadPoolExecutor.CallerRunsPolicy());System.out.println("CallerRunsPolicy测试开始,主线程: " + Thread.currentThread().getName());for (int i = 0; i < 5; i++) {final int taskId = i;executor.submit(() -> {System.out.printf("Task %d executed by %s%n", taskId, Thread.currentThread().getName());try { Thread.sleep(500); } catch (InterruptedException e) {}});}executor.shutdown();}// 自定义拒绝策略private static void testCustomRejectionPolicy() {ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(1),new CustomRejectedExecutionHandler());for (int i = 0; i < 5; i++) {final int taskId = i;executor.submit(() -> {System.out.println("Custom Policy - Task " + taskId + " executed");try { Thread.sleep(1000); } catch (InterruptedException e) {}});}executor.shutdown();}// 自定义拒绝处理器static class CustomRejectedExecutionHandler implements RejectedExecutionHandler {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {System.out.println("自定义拒绝策略: 任务被拒绝,尝试重新提交到备用队列");// 可以实现重试逻辑、记录日志、发送告警等try {Thread.sleep(100);if (!executor.isShutdown()) {executor.getQueue().offer(r, 500, TimeUnit.MILLISECONDS);}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}

这段代码展示了所有内置拒绝策略的行为特征,以及如何实现自定义拒绝策略来满足特定业务需求。

4.2 拒绝策略对比分析

40%30%15%10%5%拒绝策略使用场景分布AbortPolicy(快速失败)CallerRunsPolicy(调用者执行)DiscardPolicy(静默丢弃)DiscardOldestPolicy(丢弃最老)自定义策略

图4:拒绝策略使用分布饼图 - 展示不同拒绝策略在实际项目中的使用比例

5. 线程池监控与调优

5.1 监控指标与实现

public class ThreadPoolMonitor {private final ThreadPoolExecutor executor;private final ScheduledExecutorService monitorExecutor;public ThreadPoolMonitor(ThreadPoolExecutor executor) {this.executor = executor;this.monitorExecutor = Executors.newScheduledThreadPool(1);startMonitoring();}private void startMonitoring() {monitorExecutor.scheduleAtFixedRate(() -> {ThreadPoolMetrics metrics = collectMetrics();logMetrics(metrics);checkAlerts(metrics);}, 0, 5, TimeUnit.SECONDS);}private ThreadPoolMetrics collectMetrics() {return new ThreadPoolMetrics(executor.getCorePoolSize(),           // 核心线程数executor.getMaximumPoolSize(),        // 最大线程数executor.getPoolSize(),               // 当前线程数executor.getActiveCount(),            // 活跃线程数executor.getQueue().size(),           // 队列大小executor.getCompletedTaskCount(),     // 已完成任务数executor.getTaskCount()               // 总任务数);}private void logMetrics(ThreadPoolMetrics metrics) {System.out.printf("""=== 线程池监控报告 ===核心线程数: %d | 最大线程数: %d | 当前线程数: %d活跃线程数: %d | 队列大小: %d已完成任务: %d | 总任务数: %d线程池利用率: %.2f%% | 队列利用率: %.2f%%========================%n""",metrics.corePoolSize, metrics.maximumPoolSize, metrics.poolSize,metrics.activeCount, metrics.queueSize,metrics.completedTaskCount, metrics.taskCount,(double) metrics.activeCount / metrics.maximumPoolSize * 100,(double) metrics.queueSize / ((LinkedBlockingQueue<?>) executor.getQueue()).remainingCapacity() * 100);}private void checkAlerts(ThreadPoolMetrics metrics) {// 线程池利用率告警double utilization = (double) metrics.activeCount / metrics.maximumPoolSize;if (utilization > 0.8) {System.out.println("⚠️ 告警: 线程池利用率过高 " + String.format("%.2f%%", utilization * 100));}// 队列积压告警if (metrics.queueSize > 50) {System.out.println("⚠️ 告警: 任务队列积压严重,当前队列大小: " + metrics.queueSize);}}public void shutdown() {monitorExecutor.shutdown();}// 监控指标数据类static class ThreadPoolMetrics {final int corePoolSize;final int maximumPoolSize;final int poolSize;final int activeCount;final int queueSize;final long completedTaskCount;final long taskCount;ThreadPoolMetrics(int corePoolSize, int maximumPoolSize, int poolSize,int activeCount, int queueSize, long completedTaskCount, long taskCount) {this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.poolSize = poolSize;this.activeCount = activeCount;this.queueSize = queueSize;this.completedTaskCount = completedTaskCount;this.taskCount = taskCount;}}
}

这个监控系统提供了全面的线程池运行状态监控,包括关键指标收集、实时告警和性能分析功能。

5.2 性能调优策略

“在并发编程中,线程池的配置不是一成不变的艺术,而是需要根据实际负载动态调整的科学。合理的线程池配置能够在资源消耗和性能表现之间找到最佳平衡点。” —— 《Java并发编程实战》

public class ThreadPoolTuning {// CPU密集型任务线程池配置public static ThreadPoolExecutor createCpuIntensivePool() {int cpuCount = Runtime.getRuntime().availableProcessors();return new ThreadPoolExecutor(cpuCount,                           // 核心线程数 = CPU核心数cpuCount,                           // 最大线程数 = CPU核心数0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(100),     // 有界队列防止内存溢出new ThreadFactory() {private final AtomicInteger counter = new AtomicInteger(0);@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r, "CPU-Worker-" + counter.incrementAndGet());t.setDaemon(false);return t;}},new ThreadPoolExecutor.CallerRunsPolicy());}// IO密集型任务线程池配置public static ThreadPoolExecutor createIoIntensivePool() {int cpuCount = Runtime.getRuntime().availableProcessors();return new ThreadPoolExecutor(cpuCount * 2,                       // 核心线程数 = CPU核心数 * 2cpuCount * 4,                       // 最大线程数 = CPU核心数 * 460L, TimeUnit.SECONDS,              // 空闲线程存活时间new LinkedBlockingQueue<>(200),r -> {Thread t = new Thread(r, "IO-Worker-" + System.currentTimeMillis());t.setDaemon(false);return t;},new ThreadPoolExecutor.CallerRunsPolicy());}// 动态调整线程池大小public static void dynamicTuning(ThreadPoolExecutor executor) {ScheduledExecutorService tuner = Executors.newScheduledThreadPool(1);tuner.scheduleAtFixedRate(() -> {int queueSize = executor.getQueue().size();int activeCount = executor.getActiveCount();int corePoolSize = executor.getCorePoolSize();// 根据队列积压情况动态调整if (queueSize > 50 && corePoolSize < 10) {executor.setCorePoolSize(corePoolSize + 1);System.out.println("增加核心线程数至: " + (corePoolSize + 1));} else if (queueSize < 10 && activeCount < corePoolSize / 2 && corePoolSize > 2) {executor.setCorePoolSize(corePoolSize - 1);System.out.println("减少核心线程数至: " + (corePoolSize - 1));}}, 10, 10, TimeUnit.SECONDS);}
}

这段代码展示了针对不同类型任务的线程池配置策略,以及动态调优的实现方法。

6. 实战案例:Web服务线程池优化

6.1 问题场景与解决方案

@Service
public class OrderProcessingService {// 订单处理线程池 - IO密集型private final ThreadPoolExecutor orderPool;// 通知发送线程池 - 网络IO密集型private final ThreadPoolExecutor notificationPool;// 数据统计线程池 - CPU密集型private final ThreadPoolExecutor analyticsPool;public OrderProcessingService() {// 订单处理线程池配置this.orderPool = new ThreadPoolExecutor(5, 20, 60L, TimeUnit.SECONDS,new LinkedBlockingQueue<>(100),r -> new Thread(r, "OrderProcessor-" + System.currentTimeMillis()),new ThreadPoolExecutor.CallerRunsPolicy());// 通知线程池配置 - 允许更多线程处理网络IOthis.notificationPool = new ThreadPoolExecutor(3, 15, 30L, TimeUnit.SECONDS,new LinkedBlockingQueue<>(50),r -> new Thread(r, "NotificationSender-" + System.currentTimeMillis()),new ThreadPoolExecutor.DiscardOldestPolicy()  // 丢弃最老的通知任务);// 分析线程池配置 - CPU密集型任务int cpuCount = Runtime.getRuntime().availableProcessors();this.analyticsPool = new ThreadPoolExecutor(cpuCount, cpuCount, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(20),r -> new Thread(r, "Analytics-" + System.currentTimeMillis()),new ThreadPoolExecutor.AbortPolicy());}public CompletableFuture<OrderResult> processOrder(Order order) {return CompletableFuture.supplyAsync(() -> {// 1. 订单验证和处理validateOrder(order);return processOrderLogic(order);}, orderPool).thenCompose(result -> {// 2. 异步发送通知CompletableFuture<Void> notification = CompletableFuture.runAsync(() -> sendNotification(order, result), notificationPool);// 3. 异步更新统计CompletableFuture<Void> analytics = CompletableFuture.runAsync(() -> updateAnalytics(order, result), analyticsPool);// 4. 等待通知完成,但不等待统计(允许异步)return notification.thenApply(v -> result);}).exceptionally(throwable -> {System.err.println("订单处理失败: " + throwable.getMessage());return new OrderResult(false, "处理失败");});}private void validateOrder(Order order) {// 订单验证逻辑if (order == null || order.getAmount() <= 0) {throw new IllegalArgumentException("无效订单");}simulateWork(100); // 模拟验证耗时}private OrderResult processOrderLogic(Order order) {// 模拟订单处理逻辑simulateWork(500);return new OrderResult(true, "订单处理成功");}private void sendNotification(Order order, OrderResult result) {// 模拟发送通知(网络IO)simulateWork(200);System.out.println("通知已发送: " + order.getId());}private void updateAnalytics(Order order, OrderResult result) {// 模拟数据分析(CPU密集型)simulateWork(300);System.out.println("统计已更新: " + order.getId());}private void simulateWork(long millis) {try {Thread.sleep(millis);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}@PreDestroypublic void shutdown() {shutdownPool(orderPool, "OrderPool");shutdownPool(notificationPool, "NotificationPool");shutdownPool(analyticsPool, "AnalyticsPool");}private void shutdownPool(ThreadPoolExecutor pool, String name) {pool.shutdown();try {if (!pool.awaitTermination(30, TimeUnit.SECONDS)) {pool.shutdownNow();System.out.println(name + " 强制关闭");}} catch (InterruptedException e) {pool.shutdownNow();Thread.currentThread().interrupt();}}// 订单和结果类static class Order {private String id;private double amount;public Order(String id, double amount) {this.id = id;this.amount = amount;}public String getId() { return id; }public double getAmount() { return amount; }}static class OrderResult {private boolean success;private String message;public OrderResult(boolean success, String message) {this.success = success;this.message = message;}public boolean isSuccess() { return success; }public String getMessage() { return message; }}
}

这个实战案例展示了在Web服务中如何根据不同任务特性配置专用线程池,实现任务的并行处理和资源的合理分配。

6.2 系统架构图

存储层
线程池处理层
API层
数据库
Database
Redis缓存
Cache
消息队列
MQ
订单处理线程池
OrderPool
核心:5 最大:20
通知发送线程池
NotificationPool
核心:3 最大:15
数据分析线程池
AnalyticsPool
核心:CPU数 最大:CPU数
Order Controller
Order Service

图5:订单处理系统架构图 - 展示多线程池协作的完整系统架构

总结

通过这次深入的Java线程池探索之旅,我深刻体会到了线程池在现代Java应用中的重要地位。作为励志成为糕手,我想和大家分享几个关键的心得体会。

首先,线程池不仅仅是一个技术工具,更是一种资源管理的哲学。它教会我们如何在有限的资源下实现最大的效率,这种思维方式在软件架构设计中具有普遍的指导意义。通过合理配置核心参数,我们能够在响应速度、吞吐量和资源消耗之间找到最佳平衡点。

其次,监控和调优是线程池应用的关键环节。在实际项目中,我发现很多性能问题都源于线程池配置不当或缺乏有效监控。建立完善的监控体系,不仅能够及时发现问题,还能为后续的优化提供数据支撑。动态调优机制更是让系统具备了自适应能力,能够根据实际负载情况自动调整资源配置。

再者,不同类型的任务需要不同的线程池策略。CPU密集型任务适合较少的线程数,而IO密集型任务则可以配置更多线程来提高并发度。在复杂的业务系统中,往往需要多个专用线程池协同工作,每个线程池负责特定类型的任务,这样既能保证性能,又能实现良好的资源隔离。

最后,异常处理和优雅关闭同样重要。合适的拒绝策略能够在系统过载时保护核心功能,而优雅的关闭流程则确保了系统的稳定性和数据的完整性。这些细节往往决定了系统在极端情况下的表现。

线程池的学习让我更加深刻地理解了并发编程的精髓:不是简单地增加线程数量,而是要科学地管理和调度线程资源。在未来的开发工作中,我会继续深入研究并发编程的各个方面,为构建高性能、高可用的系统贡献自己的力量。

🌟 我是 励志成为糕手 ,感谢你与我共度这段技术时光!
✨ 如果这篇文章为你带来了启发:
✅ 【收藏】关键知识点,打造你的技术武器库
💡【评论】留下思考轨迹,与同行者碰撞智慧火花
🚀 【关注】持续获取前沿技术解析与实战干货
🌌 技术探索永无止境,让我们继续在代码的宇宙中:
• 用优雅的算法绘制星图
• 以严谨的逻辑搭建桥梁
• 让创新的思维照亮前路
📡 保持连接,我们下次太空见!

参考链接

  1. Oracle Java Documentation - Executor Framework
  2. Java Concurrency in Practice - ThreadPoolExecutor
  3. Spring Framework - Task Execution and Scheduling
  4. Baeldung - Java ThreadPoolExecutor Guide
  5. IBM Developer - Java concurrency utilities

关键词标签

Java线程池 ThreadPoolExecutor 并发编程 性能优化 拒绝策略

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习——模型架构

有监督学习 线性模型 多元线性回归&#xff1a;预测连续的数值&#xff08;如房价、销量&#xff09;。 逻辑回归&#xff1a;解决二分类问题&#xff08;如判断邮件是否是垃圾邮件&#xff09;&#xff0c;输出概率。 非线性模型 决策树&#xff1a;通过一系列if-then规则进行…

深入理解Kafka事务

一 kafka事务介绍1.1 Kafka事务的作用Exactly-Once Semantics (EOS)&#xff1a;在“消费 → 处理 → 生产”的流式链路里避免重复写与重复读带来的副作用&#xff0c;确保“处理一次且仅一次”的可见效果。跨分区 / 跨 Topic 原子性&#xff1a;将一次处理内写入的多分区多主题…

RabbitMinQ(模拟实现消息队列项目)

目录 一.消息队列背景 二.需求分析 核心概念: BrokerServer: BrokerServer的核心API: 交换机Exchange: 持久化&#xff1a; 网络通信&#xff1a; 消息应答&#xff1a; 三、模块划分 四、创建项目 五、创建核心类 Exchange: MSGQueue: Binding: Message: 六.…

如何构建StarRocks官方文档

不知道是网络问题还是官网问题&#xff0c;StarRocks文档经常出现卡顿的情况&#xff0c;曾经构建过Flink文档&#xff0c; 所以也想尝试自己构建一个StarRocks的本地官方文档 断断续续折腾了好几天&#xff0c;就不废话了&#xff0c;直接上实际步骤 1. 环境 1.1 Linux环境 …

堡垒机(跳板机)入门指南:构建更安全的多服务器运维架构

随着你的业务不断扩张&#xff0c;你云上服务器的数量&#xff0c;是不是也从一台&#xff0c;变成了三台、五台、甚至一个由几十台机器组成的庞大集群&#xff1f;你像一个尽职的“国王”&#xff0c;为你王国的每一座“城池”&#xff08;每一台服务器&#xff09;&#xff0…

(链表)Leetcode206链表反转+Leetcode6删除链表的倒数第N个结点+虚拟头节点使用

虚拟头结点的作用是&#xff1a;简化插入/删除逻辑方便返回头节点减少边界错误 Leetcode206链表反转 206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 头插法 # Definition for singly-linked list. # class ListNode(object): # def __init__(self, val0, nextN…

自然语言处理NLP:嵌入层Embedding中input_dim的计算——Tokenizer文本分词和编码

1. 词汇表大小&#xff08;input_dim&#xff09;计算方法 嵌入层Embedding中的input_dim是根据数据中所有唯一词&#xff08;或字&#xff09;的总数来决定的。可以通过Tokenizer文本分词和编码得到。 简单说&#xff0c;Tokenizer 是一个文本分词和编码器&#xff0c;它主要做…

python中的分代垃圾回收机制的原理【python进阶二、2】

1. 分代设计思想Python 将对象按存活时间分为三代&#xff08;Generation 0, 1, 2&#xff09;&#xff1a;0代&#xff08;年轻代&#xff09;&#xff1a;新创建的对象。1代&#xff08;中年代&#xff09;&#xff1a;经历一次GC扫描后存活的对象。2代&#xff08;老年代&am…

【后端】云服务器用nginx配置域名访问前后端分离项目

云服务器有多个服务&#xff08;前端 3000 端口、后端 8288 端口&#xff0c;甚至还有别的服务&#xff09;。希望用户只输入 域名&#xff08;比如 https://example.com&#xff09;&#xff0c;而不是 example.com:3000、example.com:8288。本质上是要做 端口隐藏 域名统一入…

软考中级数据库系统工程师学习专篇(67、数据库恢复)

67、数据库恢复数据库故障恢复中基于检查点的事务分类与处理策略在数据库系统发生故障后的恢复过程中&#xff0c;​检查点&#xff08;Checkpoint&#xff09;​​ 技术是关键机制&#xff0c;它能有效缩小恢复范围&#xff0c;减少需要扫描的日志量&#xff0c;从而加速恢复进…

SpringBoot 分库分表 - 实现、配置与优化

分库分表&#xff08;Database Sharding&#xff09;是一种数据库架构优化技术&#xff0c;通过将数据分散到多个数据库或表中&#xff0c;以应对高并发、大数据量场景&#xff0c;提升系统性能和扩展性。 在 Spring Boot 中&#xff0c;分库分表可以通过框架支持&#xff08;如…

爬虫代理实操:选择可靠的HTTP(S)代理的方法

在爬虫工作里&#xff0c;选对代理协议&#xff08;HTTP/HTTPS&#xff09;只是第一步&#xff0c;更关键的是找到 “可靠” 的代理 —— 哪怕是 HTTPS 代理&#xff0c;若节点不稳定、IP 纯净度低&#xff0c;照样会频繁被封&#xff0c;反而耽误采集进度。这几年踩过不少坑&a…

数据库常见故障类型

数据库常见故障类型数据库系统运行过程中可能发生的故障主要分为以下三类&#xff0c;其破坏性由小到大&#xff1a;故障类型别名根本原因影响范围典型例子​1. 事务故障​逻辑故障事务内部的程序逻辑错误或输入异常。​单个或少量事务。- 输入数据不合法&#xff08;如除零错误…

【Android】Span富文本简介

一&#xff0c;概述android.text包下span体系类&#xff0c;主要指Spanned、Spannable、ParagraphStyle、CharacterStyle实现类。Android通过Span体系&#xff0c;搭建了富文本API&#xff0c;其中Spanned、Spannable实现了CharSequence接口&#xff0c;旨在映射段落start~end之…

【HTML】draggable 属性:解锁网页交互新维度

一、简介 在Web开发中&#xff0c;用户与内容的交互方式直接影响用户体验的深度。在 HTML 中&#xff0c;draggable 是一个全局属性&#xff0c;通过简单配置即可让任意元素实现拖拽功能。也可通过结合 draggable 属性和 JavaScript 事件&#xff0c;可以实现丰富的拖放交互功能…

如何在Github中创建仓库?如何将本地项目上传到GitHub中?

1.1 点击New repository&#xff08;这个是创建代码仓库的意思&#xff09;初次完成后只有一个文件最后&#xff1a;在本地git clone 项目地址然后把项目文件复制到git的文件夹内再提交到远程仓库git add . git commit -m "修改https"git push origin mainmain为分支…

【前端教程】HTML 基础界面开发

一、网站导航栏设计与实现 导航栏是网站的重要组成部分&#xff0c;负责引导用户浏览网站的各个板块。以下是一个实用的导航栏实现方案&#xff1a; 实现代码 HTML 结构&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8" /&…

【学Python自动化】 6. Python 模块系统学习笔记

一、模块基础 什么是模块&#xff1f;包含 Python 定义和语句的 .py 文件解决代码复用和组织问题每个模块有自己的命名空间创建模块示例# fibo.py - 斐波那契模块 def fib(n):"""打印小于n的斐波那契数列"""a, b 0, 1while a < n:print(a, e…

机器学习-时序预测2

门控循环单元GRU 接着机器学习-时序预测1-CSDN博客这个说&#xff0c;GRU是LSTM的一个简化而高效的变体&#xff0c;都使用“门控机制”来控制信息流&#xff0c;但它通过合并一些组件&#xff0c;使结构更简单、参数更少、计算更快&#xff0c;同时在许多任务上性能与 LSTM 相…

数据湖与数据仓库

大数据前沿技术详解 目录 数据湖技术湖仓一体架构数据网格实时流处理技术云原生数据技术数据治理与血缘AI原生数据平台边缘计算与大数据 核心内容包括&#xff1a; 数据湖技术 - 架构模式、技术栈、面临的挑战 湖仓一体架构 - Delta Lake、Iceberg、Hudi等主流实现 数据网格…