当前位置: 首页 > news >正文

多线程篇-5--线程分类(线程类型,springboot中常见线程类型,异步任务线程)

常见的线程类型包括用户线程(User Threads)、守护线程(Daemon Threads)、主线程(Main Thread)、工作线程(Worker Threads)和线程池中的线程。

一、用户线程(User Threads)

特点:

  • 用户线程是普通的Java线程,通常由程序员显式创建。
  • 用户线程在程序运行期间一直存在,直到它们完成任务或程序终止。

代码示例:

public class UserThreadExample {public static void main(String[] args) {Thread userThread = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("User thread running: " + i);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});userThread.start();}
}

2、守护线程(Daemon Threads)

特点:

  • 守护线程是在后台运行的线程,它们通常用于为其他线程提供服务。
  • 当所有用户线程都结束时,JVM会自动终止守护线程并退出。(即使守护线程没有执行完任务,也会被JVM强制退出,所以主要业务一定不能放在守护线程中执行)
  • 守护线程通常用于执行一些辅助任务,如垃圾回收、日志记录等。

代码示例:

public class DaemonThreadExample {public static void main(String[] args) {Thread daemonThread = new Thread(() -> {while (true) {System.out.println("Daemon thread running...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});daemonThread.setDaemon(true);  // 设置为守护线程,就这一句就够了daemonThread.start();// 主线程休眠一段时间后结束try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}
}

解释:

  • 创建一个新的线程daemonThread,并将其设置为守护线程。
  • 守护线程无限循环运行,每秒打印一条消息。
  • 主线程休眠5秒后结束,此时JVM会自动终止,守护线程也会被终止。

3、主线程(Main Thread)

特点:

  • 主线程是每个Java应用程序的入口点,它是JVM在启动时自动创建的第一个线程。
  • 主线程负责执行main方法中的代码。
  • 当主线程结束时,如果还有其他用户线程在运行,JVM会继续运行这些线程。

代码示例:

public class MainThreadExample {public static void main(String[] args) {System.out.println("Main thread started");Thread userThread = new Thread(() -> {System.out.println("User thread running...");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}});userThread.start();  // 用户线程启动,实际上就是主线程干的事情System.out.println("Main thread ending");}
}

解释:

  • 主线程执行main方法中的代码。
  • 创建并启动一个用户线程userThread。
  • 主线程在启动用户线程后继续执行打印,之后就结束了。
  • 用户线程会继续运行,直到完成任务。

4、工作线程(Worker Threads)

特点:

  • 工作线程通常用于执行具体的任务,它们可以是用户线程或守护线程。
  • 工作线程通常由线程池管理,用于处理任务队列中的任务。
  • 工作线程可以提高应用程序的并发性和性能。

代码示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class WorkerThreadExample {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(2);  // 创建固定大小的线程池for (int i = 0; i < 5; i++) {int taskId = i;executor.submit(() -> {System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}});}executor.shutdown();  // 关闭线程池}
}

解释:

  • 创建一个固定大小为2的线程池executor。
  • 提交5个任务到线程池,每个任务在执行时会打印任务ID和当前线程名称。
  • 调用shutdown方法关闭线程池,等待所有任务完成。

5、线程池中的线程

特点:

  • 线程池中的线程是由线程池管理的,它们可以重复使用,减少了创建和销毁线程的开销。
  • 线程池可以控制并发线程的数量,避免过多的线程消耗系统资源。
  • 线程池通常用于处理大量的短期任务。

代码示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {ExecutorService executor = Executors.newCachedThreadPool();  // 创建可缓存线程池for (int i = 0; i < 10; i++) {int taskId = i;executor.submit(() -> {System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}});}executor.shutdown();  // 关闭线程池}
}

解释:

  • 创建一个可缓存线程池executor,它会根据需要创建新的线程。
  • 提交10个任务到线程池,每个任务在执行时会打印任务ID和当前线程名称。
  • 调用shutdown方法关闭线程池,等待所有任务完成。

6、线程分类总结

(1)、用户线程:普通的Java线程,由程序员显式创建。
(2)、守护线程:后台线程,用于提供服务,当所有用户线程结束时自动终止。
(3)、主线程:JVM自动创建的第一个线程,执行main方法中的代码。
(4)、工作线程:用于执行具体任务的线程,通常由线程池管理。
(5)、线程池中的线程:由线程池管理的线程,可以重复使用,减少开销。

7、springboot常见线程类型

(1)、主线程(Main Thread)

1、概述

  • 这是Spring Boot应用启动时由JVM创建的第一个线程。
  • 主线程负责启动Spring Boot应用,加载配置,初始化Spring容器等。

2、创建时机

  • 应用启动时,由JVM自动创建。

代码示例

@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

(2)、Tomcat/NIO线程(接受客户端请求用)

1、概述

  • 如果你的Spring Boot应用使用了嵌入式的Tomcat服务器,Tomcat会创建多个线程来处理HTTP请求。
  • 这些线程通常是NIO线程(非阻塞线程,可异步),负责接收客户端请求并处理响应。

2、创建时机

  • 当Spring Boot应用启动并初始化嵌入式Tomcat服务器时。

配置文件示例
无需编码,仅配置即可,不配置也可以会有默认配置。

server:port: 8080tomcat:max-threads: 200  # 最大线程数min-spare-threads: 10  # 最小空闲线程数

(3)、定时任务线程(Scheduled Tasks)

1、概述

  • 如果你在Spring Boot应用中使用了定时任务(如@Scheduled注解),Spring Boot会创建一个或多个线程来执行这些定时任务。
  • 这些线程通常由TaskScheduler管理。

2、创建时机

  • 当Spring Boot应用启动并初始化定时任务时。

代码示例

@Configuration
@EnableScheduling
public class SchedulerConfig {
}@Component
public class ScheduledTasks {@Scheduled(fixedRate = 5000)   // 自动创建定时任务线程监听并执行public void performTask() {System.out.println("Executing scheduled task at " + LocalDateTime.now());}
}

(4)、异步任务线程(Async Tasks)

1、概述

  • 如果你在Spring Boot应用中使用了异步方法(如@Async注解),Spring Boot会创建一个或多个线程来执行这些异步任务。
  • 这些线程通常由TaskExecutor管理。

这个在附录中在详细说明。

(5)、自定义线程

1、概述

  • 你可以在Spring Boot应用中手动创建和管理线程,例如通过实现Runnable接口或继承Thread类。

2、创建时机

  • 在你需要的时候手动创建。

代码示例

@Component
public class CustomThreadExample {@PostConstructpublic void startCustomThread() {Thread customThread = new Thread(() -> {while (true) {System.out.println("Custom thread running at " + LocalDateTime.now());try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}});customThread.start();}
}

附录:

异步任务线程(Async Tasks)

1、概述

  • 如果你在Spring Boot应用中使用了异步方法(如@Async注解),Spring Boot会创建一个或多个线程来执行这些异步任务,主线程不会阻塞会继续执行后面的代码。
  • 这些线程通常由TaskExecutor管理。
  • 使用异步任务,使用@EnableAsync开启后(主方法等配置入口),在需要的方法上添加@Async注解即可。
2、异步任务线程的作用
(1)、提高响应性
  • 异步任务线程可以在后台执行耗时的操作,而不阻塞主线程或请求处理线程。这样,主线程可以继续处理其他请求,提高系统的整体响应性。
(2)、优化资源利用
  • 对于耗时较长的任务,如果使用同步方式处理,可能会占用宝贵的线程资源,导致其他任务无法及时处理。异步任务线程可以将这些任务移到后台执行,释放主线程资源。
(3)、并发处理
  • 异步任务线程可以并行处理多个任务,提高系统的并发处理能力。这对于需要处理大量并发请求的应用尤其重要。
3、异步任务特点

(1)、异步任务线程:异步任务在单独的线程中执行,不会阻塞主线程。
(2)、立即返回:异步方法调用会立即返回一个CompletableFuture对象,主线程可以继续执行其他任务。
(3)、回调机制:使用thenAccept等方法注册回调函数,这些回调函数在异步任务完成时被调用(被线程池的其他线程调用),不会阻塞主线程。

4、常见的异步任务场景

(1)、邮件发送

  • 发送邮件是一个耗时操作,通常需要几秒钟甚至更长时间。使用异步任务线程可以在后台发送邮件,而不会阻塞主线程。

(2)、文件上传和下载

  • 文件上传和下载操作通常涉及大量的I/O操作,使用异步任务线程可以避免阻塞主线程,提高系统的响应性。

(3)、数据处理和计算

  • 对于复杂的数据处理和计算任务,使用异步任务线程可以将这些任务移到后台执行,释放主线程资源。

(4)日志记录

  • 日志记录操作通常需要写入磁盘,使用异步任务线程可以避免阻塞主线程,提高系统的性能。
5、异步任务线程与异步请求处理的区别

前者是优化请求响应速度,把不重要或耗时的事情放在后台慢慢执行,主线程可以继续干其他事情或直接返回的一种处理方式;后者是并行可同时接受客户端的多个请求,两者完全不是一回事,需要注意下。

(1)、异步任务线程
  • 用于处理耗时较长的后台任务。
  • 通常由开发人员手动创建和管理。
  • 使用@Async注解和TaskExecutor来实现。
    即:用于处理耗时较长的后台任务,提高系统的响应性和并发处理能力。
(2)、异步请求处理
  • 用于处理HTTP请求的异步响应。
  • 通常由Web框架(如Spring MVC,springboot)自动支持。
  • 使用CompletableFuture、DeferredResult等异步API来实现。
    即:用于处理HTTP请求的异步响应,通常由Web框架自动支持。
6、如何使用异步任务
(1)、@EnableAsync

@EnableAsync注解只需要在一个配置类上启用一次,即可在整个应用程序中启用异步任务的支持。即:开启后会告诉Spring框架扫描并管理带有@Async注解的方法。

代码示例:

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;@Configuration
@EnableAsync
public class AsyncConfig {// 配置类可以包含其他Bean和配置
}
(2)、@Async

1、@Async注解用于标记那些需要异步执行的方法上。注意,方法必须在一个Spring管理的Bean中,否则不会扫描到。
2、@Async标记的方法将在异步任务线程中执行,不会阻塞当前线程,而是立即返回一个Future对象或CompletableFuture对象。(这个Future对象现在是无法获取结果的,只能通过定义回调的方式用于异步任务完成后再去通知调用的线程,当然如果无需等待结果的也可以直接忽略返回结果)。

(3)、异步线程池

默认情况下,Spring是使用一个简单的线程池来执行异步任务。你也可以自定义线程池注入spring容器中,以更好地控制异步任务的执行。

3.1、自定义线程池示例

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;@Configuration
@EnableAsync       // 开启异步任务
public class AsyncConfig {@Bean                      // 注入线程池public ThreadPoolTaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(2);executor.setMaxPoolSize(5);executor.setQueueCapacity(100);executor.setThreadNamePrefix("Async-");executor.initialize();return executor;}
}

3.2、控制器示例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class AsyncController {@Autowiredprivate AsyncService asyncService;@GetMapping("/send-email")public String sendEmail(@RequestParam String recipient, @RequestParam String message) {// 调用异步方法CompletableFuture<String> result = asyncService.sendEmail(recipient, message);// 处理异步结果result.thenAccept(response -> {   // 定义的回调方法,不会阻塞主线程,主线程会定义完成之后直接跳过该方法,往后执行。在异步任务完成后,真正执行回调方法代码的是线程池中的线程。System.out.println("Response: " + response);   // 异步任务完成后,由线程池中的线程执行,主线程不会执行。});return "Request accepted, email will be sent asynchronously";}
}

3.3、异步方法

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;@Service
public class AsyncService {@Asyncpublic CompletableFuture<String> sendEmail(String recipient, String message) {// 模拟耗时操作try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}// 发送邮件System.out.println("Email sent to " + recipient + ": " + message);return CompletableFuture.completedFuture("Email sent successfully");}
}

解释一下:
1、异步方法的调用:

  • AsyncControllersendEmail方法中,调用asyncService.sendEmail方法。
  • sendEmail方法被标记为@Async,因此它会在一个异步任务线程中执行。
  • 方法调用会立即返回一个CompletableFuture<String>对象,标识异步任务的结果对象。(这个对象现在是无法获取执行结果的,因为还没有执行完成,需要想要调用线程得到响应,可以通过定义回调的方式在异步任务完成后再通知调用的线程)。
    2、处理异步结果:
  • 使用result.thenAccept(response -> { ... })方法来处理异步任务的结果。
  • thenAccept方法注册一个回调函数,当异步任务完成时,回调函数会被调用,并传入任务的结果。
  • 这个回调函数在异步任务线程中执行,不会阻塞主线程。
    3、立即返回响应:
  • AsyncControllersendEmail方法在调用异步方法后立即返回一个字符串"Request accepted, email will be sent asynchronously"
  • 这个响应告诉客户端请求已经被接受,邮件将在后台异步发送。

学海无涯苦作舟!!!

相关文章:

多线程篇-5--线程分类(线程类型,springboot中常见线程类型,异步任务线程)

常见的线程类型包括用户线程&#xff08;User Threads&#xff09;、守护线程&#xff08;Daemon Threads&#xff09;、主线程&#xff08;Main Thread&#xff09;、工作线程&#xff08;Worker Threads&#xff09;和线程池中的线程。 一、用户线程&#xff08;User Thread…...

docker快速部署gitlab

文章目录 场景部署步骤默认账号密码效果 场景 新增了一台机器, 在初始化本地开发环境&#xff0c;docker快速部署gitlab 部署步骤 编写dockerfile version: 3.7services:gitlab:image: gitlab/gitlab-ce:latestcontainer_name: gitlabrestart: alwayshostname: gitlabenviron…...

C# 数据类型详解:掌握数据类型及操作为高效编码奠定基础

本文将带你深入了解C#中各种数据类型的特点、用途和最佳实践&#xff0c;让你不仅能熟练运用基本类型&#xff0c;还能掌握如何在实际项目中做出最合适的选择。 目录 C#基本语法 C#数据类型 C#类型转换 C#变量常量 C#基本语法 在学习C#之前我们要先知道C#的基础构建是由哪些…...

burp2

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…...

[ACTF2020 新生赛]BackupFile--详细解析

信息搜集 让我们寻找源文件&#xff0c;目录扫描&#xff1a; 找到了/index.php.bak文件&#xff0c;也就是index.php的备份文件。 后缀名是.bak的文件是备份文件&#xff0c;是文件格式的扩展名。 我们访问这个路径&#xff0c;就会直接下载该备份文件。 我们把.bak后缀删掉…...

循环神经网络(RNN)简述

RNN及其变体 1、概述 (一)、概念 RNN(Recurrent Neural Network), 中文称作循环神经网络, 它一般以序列数据为输入, 通过网络内部的结构设计有效捕捉序列之间的关系特征, 一般也是以序列形式进行输出。 RNN的循环机制使模型隐层**上一时间步产生的结果, 能够作为当下时间步…...

九、Ubuntu Linux操作系统

一、Ubuntu简介 Ubuntu Linux是由南非人马克沙特尔沃思(Mark Shutteworth)创办的基于Debian Linux的操作系统&#xff0c;于2004年10月公布Ubuntu是一个以桌面应用为主的Linux发行版操作系统Ubuntu拥有庞大的社区力量&#xff0c;用户可以方便地从社区获得帮助其官方网站:http…...

SpringBoot 新冠密接者跟踪系统:校园疫情防控的智能守护者

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自古…...

【Ubuntu】E: Unable to locate package xxx

报错描述 在 Ubuntu 上 执行 apt install xxx 出现下面的报错&#xff1a; 即无法定位到该 Package&#xff0c;一般形式如下&#xff1a; # apt install xxx Reading package lists... Done Building dependency tree... Done Reading state information... Done E: Unable …...

vue多页面应用集成时权限处理问题

在多页面应用&#xff08;MPA&#xff09;中&#xff0c;权限管理通常会涉及到每个页面的访问控制、身份验证、以及权限校验。以下是几种常见的权限处理方式&#xff1a; 1. 前端路由权限控制 原理&#xff1a;虽然是多页面应用&#xff0c;通常每个页面会独立加载和渲染&…...

Socket编程(TCP/UDP详解)

前言&#xff1a;之前因为做项目和找实习没得空&#xff0c;计算机网络模块并没有写成博客&#xff0c;最近得闲了&#xff0c;把计算机网络模块博客补上。 目录 一&#xff0c;UDP编程 1&#xff09;创建套接字 2&#xff09;绑定端口号 3&#xff09;发送与接收数据 4&…...

qt QConicalGradient详解

1、概述 QConicalGradient是Qt框架中QGradient的一个子类&#xff0c;它用于创建锥形渐变效果。锥形渐变是从一个中心点出发&#xff0c;沿着360度的圆周扩散的颜色渐变。这种渐变通常用于模拟光线旋转、创建彩虹效果或实现其他复杂的颜色过渡。QConicalGradient允许你定义渐变…...

存储过程与自然语言处理逻辑的不同与结合

在现代软件开发中&#xff0c;存储过程与自然语言处理&#xff08;NLP&#xff09;逻辑都发挥着重要作用。存储过程是一种在数据库内部运行的预编译程序&#xff0c;通常用于处理与数据相关的任务&#xff0c;例如插入、更新、删除数据以及复杂的查询操作。而自然语言处理&…...

了解Linux —— 理解其中的权限

前言 在了解Linux权限之前&#xff0c;先来探讨我们使用的shell 命令它到底是什么&#xff1f; Linux 是一个操作系统&#xff0c;我们称其为内核(kernel) &#xff0c;正常情况下&#xff0c;我们一般用户操作并不是去直接使用内核&#xff0c;而是通过kernel 的外壳程序&…...

知识图谱嵌入与因果推理的结合

知识图谱通过节点&#xff08;实体&#xff09;和边&#xff08;关系&#xff09;来表示现实世界中的信息&#xff0c;但如何将这些信息转化为可进行推理和决策的形式&#xff0c;仍然是一个挑战。 另一方面&#xff0c;因果推理&#xff08;Causal Inference&#xff09;作为…...

STM32 PWM波形详细图解

目录 前言 一 PWM介绍 1.1 PWM简介 1.2 STM32F103 PWM介绍 1.3 时钟周期与占空比 二.引脚映像关系 2.1引脚映像与寄存器 2.2 复用功能映像 三. PWM 配置步骤 3.1相关原理图 3.2配置流程 3.2.1 步骤一二&#xff1a; 3.2.2 步骤三&#xff1a; 3.2.3 步骤四五六七&#xff1a; …...

Python Web 开发 FastAPI 入门:从基础架构到框架比较

Python Web 开发 FastAPI 入门&#xff1a;从基础架构到框架比较 目录 &#x1f5a5;️ Web 服务器概述&#xff08;如 Nginx、Apache&#xff09;&#x1f517; 前后端分离架构详解&#x1f504; HTTP 路由和请求处理机制&#x1f9f0; Web 框架概述&#xff1a;Django、Fla…...

基于STM32的智能仓库管理系统设计

目录 引言环境准备 硬件准备软件准备智能仓库管理系统基础 控制系统架构功能描述代码实现&#xff1a;实现智能仓库管理系统 4.1 RFID标签读取模块4.2 库存管理模块4.3 数据显示与监控模块4.4 无线通信模块应用场景&#xff1a;智能仓库管理系统优化问题解决方案与优化收尾与总…...

排序算法--堆排序【图文详解】

“留在码头的船才最安全” “但亲爱的&#xff0c;那不是造船的目的。 堆--插入heapInsert 原来有一个大根堆&#xff0c;如图&#xff1a; 现在要新插入一个数字50&#xff0c;进行插入 流程&#xff1a;和父亲相比&#xff0c;如果比父亲大&#xff0c;和父亲交换&#xff…...

FCBP 认证考试要点摘要

理论知识 数据处理与分析&#xff1a;包括数据的收集、清洗、转换、存储等基础操作&#xff0c;以及数据分析方法&#xff0c;如描述性统计分析、相关性分析、数据挖掘算法等的理解和应用 。数据可视化&#xff1a;涉及图表类型的选择与应用&#xff0c;如柱状图、折线图、饼图…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...