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

Java Executor ScheduledExecutorService 源码

前言


 相关系列

  • 《Java & Executor & 目录》
  • 《Java & Executor & ScheduledExecutorService & 源码》
  • 《Java & Executor & ScheduledExecutorService & 总结》
  • 《Java & Executor & ScheduledExecutorService & 问题》
     

 涉及内容

  • 《Java & Executor & 总结》
  • 《Java & Executor & ExecutorService & 总结》
     
     

概述


 简介

在这里插入图片描述

    ScheduledExecutorService @ 调度执行器服务接口定义了“调度”概念。调度执行器服务接口是在ExecutorService @ 执行器服务接口的子接口,其在原本的基础上再度新增了“调度”概念。所谓调度可以理解为定时执行,即令任务在指定时间点被执行,而非在可执行时立即执行。

    调度执行器服务接口将“调度”概念细分为“延迟/周期”。“延迟”概念顾名思义,即任务会在其可执行的时间点上延迟指定时间后执行。这种延迟是人为规定的,与任务的执行机制无关。而大部分执行器由于自身任务执行机制的原因虽然也可能造成延迟,但这种延迟并非人为规定,因此与“延迟”概念没有关系。由此可知虽然调度执行器服务接口支持指定任务的延迟时间,但在任务具体执行时其实际延迟时间可能比指定延迟时间更长/短。此外调度执行器服务接口支持零/负延迟,当延迟时间被指定为零/负值时任务会被立即执行。关于“周期”的概念很也好理解,即令任务周期性地重复执行。通过对这两种概念进行组合,调度执行器服务接口可实现无延迟单次执行/有延迟单次执行/无延迟周期执行/有延迟周期执行四种任务调度形式。
 
 

源码


/** ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************//******* Written by Doug Lea with assistance from members of JCP JSR-166* Expert Group and released to the public domain, as explained at* http://creativecommons.org/publicdomain/zero/1.0/*/package juc;import java.util.Date;/*** An {@link ExecutorService} that can schedule commands to run after a given delay, or to execute periodically.* 一个可以调度命令在指定延迟后运行,或周期性执行的执行器服务。* <p>* The {@code schedule} methods create tasks with various delays and return a task object that can be used to cancel or* check execution. The {@code scheduleAtFixedRate} and {@code scheduleWithFixedDelay} methods create and execute* tasks that run periodically until cancelled.* schedule()方法随着可变的延迟创建任务并返回一个可用于取消和检查执行的任务对象。scheduleAtFixedRate()和* scheduleWithFixedDelay()方法会周期性地创建及执行任务直至取消。* <p>* Commands submitted using the {@link Executor#execute(Runnable)} and {@link ExecutorService} {@code submit} methods* are scheduled with a requested delay of zero. Zero and negative delays (but not periods) are also allowed in* {@code schedule} methods, and are treated as requests for immediate execution.* 使用execute和submit方法递交的命令随着0延迟请求调度。0和负延迟(但不可以是周期)在调度方法中也允许,并且被作为* 立即执行请求对待。* <p>* All {@code schedule} methods accept <em>relative</em> delays and periods as arguments, not absolute times or dates.* It is a simple matter to transform an absolute time represented as a {@link Date} to the required form. For example, to* schedule at a certain future {@code date}, you can use:* {@code schedule(task, date.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS)}.* Beware however that expiration of a relative delay need not coincide with the current {@code Date} at which the task* is enabled due to network time synchronization protocols, clock drift, or other factors.* 所有调度方法都接受相关联的延迟和周期作为参数【即存在针对各种时间格式的重载方法】,不单纯是时间或日期。这是个* 转变单纯时间作为日期用于需要格式的简单问题。例如,为了在某个未来时间调度,你可以使用:* schedule(task, date.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS)* 此外注意:由于网络时间同步规约,时钟漂移,或者其它因素,相对延迟的到期日期不必与启用任务的当前日期一致【即实际* 执行时间可能与计划执行时间存在误差...妈的说的这么晦涩是想难到谁?】。* <p>* The {@link Executors} class provides convenient factory methods for the ScheduledExecutorService implementations* provided in this package.* Executors类提供便利的调度执行器服务实现(在当前包中实现)的工厂方法。* <h3>Usage Example</h3>* 使用模板* <p>* Here is a class with a method that sets up a ScheduledExecutorService to beep every ten seconds for an hour:* 这是一个随着方法建立一个调度线程池执行器来在一小时内每十秒鸣响的类:* <pre> {@code* import static TimeUnit.*;* class BeeperControl {*   // 通过工厂方法快速创建一个调度线程池执行器。*   private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);**   public void beepForAnHour() {*     final Runnable beeper = new Runnable() {*       public void run() {*         System.out.println("beep");*       }*     };**     final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);*     scheduler.schedule(new Runnable() {*       public void run() {*         beeperHandle.cancel(true);*       }*     }, 60 * 60, SECONDS);*   }* }}</pre>** @author Doug Lea* @since 1.5*/
public interface ScheduledExecutorService extends ExecutorService {/*** Creates and executes a one-shot action that becomes enabled after the given delay.* 创建和执行一个单在指定延迟之后可用的单次活动。** @param command the task to execute 用于执行的任务* @param delay   the time from now to delay execution 用于延迟执行的基于当前的时间* @param unit    the time unit of the delay parameter 延迟参数的时间单位* @return a ScheduledFuture representing pending completion of the task and whose {@code get()} method will return* {@code null} upon completion* 一个调度未来代表任务的待定完成并且get()方法在完成后将返回null* @throws RejectedExecutionException if the task cannot be scheduled for execution*                                    拒绝执行异常:如果任务无法被调度执行* @throws NullPointerException       if command is null*                                    空指针异常:如果命令为null* @Description: ------------------------------------------------------------- 名称 -------------------------------------------------------------* 调度* @Description: ------------------------------------------------------------- 作用 -------------------------------------------------------------* 向当前调度执行器服务递交在指定延迟后执行的可运行/任务,并返回追踪/获取可运行/任务执行状态/结果的调度未来。* 由于在递交可运行/任务时没有传入用于承载可运行/任务执行结果的变量,因此调度未来实际无法获取可运行/任务的执* 行结果,故而该方法返回的调度未来的get()方法将永远返回null。* @Description: ------------------------------------------------------------- 逻辑 -------------------------------------------------------------* ----*/public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);/*** Creates and executes a ScheduledFuture that becomes enabled after the given delay.* 创建和执行一个在指定延迟后可用的调度未来。** @param callable the function to execute 用于指定的功能* @param delay    the time from now to delay execution 用于延迟执行的基于当前时间的时间* @param unit     the time unit of the delay parameter 延迟参数的时间单位* @param <V>      the type of the callable's result 可调用结果的类型* @return a ScheduledFuture that can be used to extract result or cancel* 一个可用于提取结果或取消的调度未来* @throws RejectedExecutionException if the task cannot be scheduled for execution*                                    拒绝执行异常:如果任务无法被调度执行* @throws NullPointerException       if command is null*                                    空指针异常:如果命令为null* @Description: ------------------------------------------------------------- 名称 -------------------------------------------------------------* 调度* @Description: ------------------------------------------------------------- 作用 -------------------------------------------------------------* 向当前调度执行器服务递交在指定延迟后执行的可调用/任务,并返回追踪/获取可调用/任务执行状态/结果的调度未来。* @Description: ------------------------------------------------------------- 逻辑 -------------------------------------------------------------* ----*/public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);/*** Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with* the given period; that is executions will commence after {@code initialDelay} then {@code initialDelay+period}, then* {@code initialDelay + 2 * period}, and so on. If any execution of the task encounters an exception, subsequent* executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor.  If* any execution of this task takes longer than its period, then subsequent executions may start late, but will not* concurrently execute.* 创建和执行一个在指定初始延迟之后,并随着指定周期可用的周期性活动;该执行将在初始延迟之后的initialDelay+period* 时间,initialDelay + 2 * period时间开始,等等。如果任意【一次】任务的执行遭遇异常,随后执行将被禁止。此外,任务* 将只能通过取消或执行器的终止而终止。如果任意当前任务的执行占有比它的周期更长的时间,那么随后执行可能开始的较* 晚,但不会并发地执行【一个任务一个时间只能被一条线程执行】。** @param command      the task to execute 用于执行的任务* @param initialDelay the time to delay first execution 用于延迟首次执行的时间* @param period       the period between successive executions 介于两次连续执行的周期* @param unit         the time unit of the initialDelay and period parameters 初始延迟和周期参数的时间单位* @return a ScheduledFuture representing pending completion of the task, and whose {@code get()} method will throw an* exception upon cancellation* 一个调度未来代表任务的等待执行,并且get()方法将在取消后抛出异常。* @throws RejectedExecutionException if the task cannot be scheduled for execution*                                    拒绝执行异常:如果任务无法被调度执行* @throws NullPointerException       if command is null*                                    空指针异常:如果命令为null* @throws IllegalArgumentException   if period less than or equal to zero*                                    非法参数异常:如果周期小于等于0* @Description: ------------------------------------------------------------- 名称 -------------------------------------------------------------* 按固定速率调度* @Description: ------------------------------------------------------------- 作用 -------------------------------------------------------------* 向当前调度执行器服务递交在指定初始延迟后按指定周期周期性执行的可运行/任务,并返回追踪/获取可运行/任务执行状* 态/结果的调度未来。由于在递交可运行/任务时没有传入用于承载可运行/任务执行结果的变量,因此调度未来实际无法获* 取可运行/任务的执行结果,故而该方法返回的调度未来的get()方法将永远返回null。但又因为该方法递交的可运行/任务将* 在自身没有被取消/执行中没有抛出异常/当前调度执行器服务没有被终止的情况下永远周期性地执行下去,因此调度未来* 的get()方法要么因为上述情况抛出异常,要么因为无法获取到结果而无限等待。此外,即使可运行/任务的执行时间超过周* 期,下次执行依然会在距离上次执行开始时间点的指定周期后开始,并且上次执行会被取消(虽然可能无法响应)。* @Description: ------------------------------------------------------------- 逻辑 -------------------------------------------------------------* ----*/public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);/*** Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with* the given delay between the termination of one execution and the commencement of the next.  If any execution of the* task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via* cancellation or termination of the executor.* 创建并执行一个在指定初始延迟之后可用,并随着指定介于首次执行结束和下次执行开始的延迟执行的周期型活动。如果* 任意【一次】任务的执行遭遇一场,随后执行将被禁止。此外,任务将只能通过取消或执行器的终止而终止。** @param command      the task to execute 用于执行的任务* @param initialDelay the time to delay first execution 用于延迟首次执行的时间* @param delay        the delay between the termination of one execution and the commencement of the next*                     介于首次执行终止何下次执行开始的延迟* @param unit         the time unit of the initialDelay and period parameters 初始延迟和周期参数的时间单位* @return a ScheduledFuture representing pending completion of the task, and whose {@code get()} method will throw an* exception upon cancellation* 一个调度未来代表任务的等待执行,并且get()方法将在取消后抛出异常。* @throws RejectedExecutionException if the task cannot be scheduled for execution*                                    拒绝执行异常:如果任务无法被调度执行* @throws NullPointerException       if command is null*                                    空指针异常:如果命令为null* @throws IllegalArgumentException   if period less than or equal to zero*                                    非法参数异常:如果周期小于等于0* @Description: ------------------------------------------------------------- 名称 -------------------------------------------------------------* 随固定延迟调度* @Description: ------------------------------------------------------------- 作用 -------------------------------------------------------------* 向当前调度执行器服务递交在指定初始延迟后按指定延迟周期性执行的可运行/任务,并返回追踪/获取可运行/任务执行状* 态/结果的调度未来。由于在递交可运行/任务时没有传入用于承载可运行/任务执行结果的变量,因此调度未来实际无法获* 取可运行/任务的执行结果,故而该方法返回的调度未来的get()方法将永远返回null。但又因为该方法递交的可运行/任务将* 在自身没有被取消/执行中没有抛出异常/当前调度执行器服务没有被终止的情况下永远周期性地执行下去,因此调度未来* 的get()方法要么因为上述情况抛出异常,要么因为无法获取到结果而无限等待。此外,如果可运行/任务的执行时间超过周* 期,则下次执行会在距离上次执行结束时间点的指定延迟后开始。* @Description: ------------------------------------------------------------- 逻辑 -------------------------------------------------------------* ----*/public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);}

相关文章:

Java Executor ScheduledExecutorService 源码

前言 相关系列 《Java & Executor & 目录》《Java & Executor & ScheduledExecutorService & 源码》《Java & Executor & ScheduledExecutorService & 总结》《Java & Executor & ScheduledExecutorService & 问题》 涉及内容 …...

【力扣 + 牛客 | SQL题 | 每日6题】牛客SQL热题 + 力扣hard

1. 牛客SQL热题206&#xff1a;获取每个部门中当前员工薪水最高的相关信息 1.1 题目&#xff1a; 描述 有一个员工表dept_emp简况如下: emp_nodept_nofrom_dateto_date10001d0011986-06-269999-01-0110002d0011996-08-039999-01-0110003d0021996-08-039999-01-01 有一个薪水…...

前端常见错误

搭建vueelement-ui脚手架错误 基于vue官方文档和element官方文档搭建手册报错 安装element Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist. types.js?8ad0:39 Uncaught TypeError: Cannot read property prototype of undefi…...

Edge 浏览器插件开发:图片切割插件

Edge 浏览器插件开发&#xff1a;图片切割插件 在图片处理领域&#xff0c;按比例切割图片是一个常见需求。本文将带你开发一个 Edge 浏览器插件&#xff0c;用于将用户上传的图片分割成 4 个部分并自动下载到本地。同时&#xff0c;本文介绍如何使用 cursor 辅助工具来更高效…...

银河麒麟v10 xrdp安装

为了解决科技被卡脖子的问题&#xff0c;国家正在大力推进软硬件系统的信创替代&#xff0c;对于一些平时对Linux操作系统不太熟练的用户来讲提出了更高的挑战和要求。本文以银河麒麟v10 24.03为例带领大家配置kylin v10的远程桌面。 最近公司为了配置信创开发新购了几台银河麒…...

Leetcode 删除有序数组中的重复项 Ⅱ

使用双指针来解决此问题&#xff0c;关键词“有序”数组&#xff0c;一个 index 指针用于构建新数组&#xff0c;一个 i 指针用于遍历整个数组 以下是代码的中文解释以及算法思想&#xff1a; 算法思想 这道题要求对一个有序数组进行去重&#xff0c;使得每个元素最多出现两…...

大模型学习笔记------什么是大模型

大模型学习笔记------什么是大模型 1、大模型定义2、大模型发展历程3、大模型的核心特点4、大模型的应用领域5、大模型面临的挑战6、结束语 近两年大模型超级火&#xff0c;并且相关产品迎来爆发式增长。在工作中&#xff0c;也常常接触到大模型&#xff0c;并且已经开始进行相…...

【unique_str 源码学习】

文章目录 &#xff11;&#xff0e;删除器定义2. operator->() 运算符重载3. add_lvalue_reference<element_type>::type 使用 基本原理这篇博主写的很详细 https://yngzmiao.blog.csdn.net/article/details/105725663 &#xff11;&#xff0e;删除器定义 deleter_…...

flask第一个应用

文章目录 安装一、编程第一步二、引入配置三、代码解析 安装 python环境安装的过程就不重复赘述了&#xff0c;flask安装使用命令pip install Flask即可&#xff0c;使用命令pip show Flask查看flask版本信息 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供…...

华为OD机试真题(Python/JS/C/C++)- 考点 - 细节

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题 点这里。 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。...

【C++刷题】力扣-#628-三个数的最大乘积

题目描述 给你一个整型数组 nums &#xff0c;在数组中找出由三个数组成的最大乘积&#xff0c;并输出这个乘积。 示例 示例 1 输入&#xff1a;nums [1,2,3] 输出&#xff1a;6示例 2 输入&#xff1a;nums [1,2,3,4] 输出&#xff1a;24示例 3 输入&#xff1a;nums […...

Java项目实战II基于Java+Spring Boot+MySQL的工程教育认证的计算机课程管理平台(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着工程教…...

基于微信小程序实现信阳毛尖茶叶商城系统设计与实现

作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参与学生毕业答辩指导&#xff0c;…...

设计一个灵活的RPC架构

RPC架构 RPC本质上就是一个远程调用&#xff0c;需要通过网络来传输数据。传输协议可以有多种选择&#xff0c;但考虑到可靠性&#xff0c;一般默认采用TCP协议。为了屏蔽网络传输的复杂性&#xff0c;需要封装一个单独的数据传输模块用来收发二进制数据&#xff0c;这个单独模…...

大数据计算里的Broadcast Hash Join/Shuffle Hash Join/Sort Merge Join

文章目录 Broadcast Hash Join场景 Shuffle Hash Join场景 Sort Merge Join场景 Broadcast Hash Join 场景 大表和小小表&#xff0c;直接把B表加载到内存&#xff0c;然后读块1内容和内存中数据匹配 Shuffle Hash Join 场景 大表和小表JOIN &#xff0c;小表分块后能加载…...

Java - 手写识别; 如何用spring ai和大模型做手写识别教程

识别后的文字 利用大模型提升Java手写识别&#xff1a;更简单、更高效 在Java场景中&#xff0c;我们经常需要处理手写识别的问题。过去&#xff0c;这类需求主要依赖于OCR技术&#xff0c;但其效果并不总是稳定。随着大模型的发展&#xff0c;使用大模型进行java手写识别成为…...

【Linux】用户权限管理:创建受限用户并配置特定目录访问权限

本文详细介绍了如何在 Linux 系统中创建一个名为 agent 的新用户&#xff0c;并限制其在特定目录下的权限。通过使用 useradd 命令创建用户&#xff0c;并使用 usermod 命令将新用户添加到现有用户组中&#xff0c;确保其具有适当的权限。接着&#xff0c;通过 chown 和 chmod …...

pgsql表分区和表分片设计

在设计 PostgreSQL 表分区和表分片时&#xff0c;主要目标是提高查询性能、可扩展性和数据管理的效率。以下是一些关键的设计步骤和策略&#xff1a; 1. 分区策略 水平分片&#xff1a;选择按日期进行水平分片&#xff0c;每天一个分片。这种策略适用于具有时间序列数据的场景…...

灵动AI ——视频创作新引擎 开启视觉奇幻之旅

灵动AI视频官网地址&#xff1a;https://aigc.genceai.com/ 灵动AI 科技与艺术的完美融合之作。它代表着当下最前沿的影像技术&#xff0c;为我们带来前所未有的视觉盛宴。...

AI设计、作图、画画工具哪个好用?看完这篇你就知道怎么选了

Stable Diffusion Stable Diffusion 是由 Stability AI 推出的开源 AI 文本到图像生成模型&#xff0c;以其开放性和灵活性在 AI 视觉工具领域广受欢迎。与 DALL-E 或 Midjourney 等只能依赖云计算的工具不同&#xff0c;Stable Diffusion 支持本地运行&#xff0c;也广泛兼容多…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

Python:操作 Excel 折叠

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

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...