多线程编程实例(使用CompletableFuture)

2023-05-16

关键配置:

    /**
     * 代理类对象
     */
    YrSyncWrService yrSyncWrServiceProxy;

 

// 获取代理类的对象,调用本类方法时,注解才会生效。比如@Async多线程,@Transactional事务控制
yrSyncWrServiceProxy = SpringUtil.getBean(YrSyncWrServiceImpl.class);
                // 创建指定多线程处理批次数大小数组
                CompletableFuture<Map<String, Integer>>[] completableFutureArr = new CompletableFuture[batchNums];

                CompletableFuture<Map<String, Integer>> completableFuture;

                // 每次遍历数量为 batchQueryNum 的记录,分批进行多线程处理
                for (int batchNum = 0; batchNum < batchNums; batchNum++) {
                    // 如果异步标识没值或为false
                    if (asyncFlag == null || !asyncFlag) {
                        // 同步指定类型网元(没有用代理类调用本类方法,则多线程不起作用,视为单线程处理)
                        completableFuture = syncOneNetEleTypeByBatchNum(netEleClass, metaWrFieldMapList, syncNetEleType, batchNum, netElementNameList, lastUpdateTime);
                    } else {
                        // 按批次号同步指定类型网元(多线程异步处理)//异步标志.true:异步;false或NULL:同步.
                        completableFuture = yrSyncWrServiceProxy.syncOneNetEleTypeByBatchNum(netEleClass, metaWrFieldMapList, syncNetEleType, batchNum, netElementNameList, lastUpdateTime);
                    }
                    completableFutureArr[batchNum] = completableFuture;
                }

                // 等待所有任务都执行完
                CompletableFuture.allOf(completableFutureArr).join();

                CompletableFuture<Map<String, Integer>> cf;

                // 统计成功条数
                for (int i = 0; i < completableFutureArr.length; i++) {
                    cf = completableFutureArr[i];
                    Map<String, Integer> resultMap = null;
                    try {
                        resultMap = cf.get();
                    } catch (InterruptedException e) {
                        wrAlarmTipsLogService.generateAlarmTipsLog("wr_sync_finish_" + syncNetEleType + "_add,error", syncNetEleType, e.getMessage(), "luhuiping");
                        Thread.currentThread().interrupt();//捕获到InterruptedException异常后恢复中断状态
                        log.info("sync_fail (600002) 综资同步到无线资源,正在同步当前网元【{}】,异常错误信息【{}】", 
                                syncNetEleType ,e.getMessage());
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        log.info("sync_fail (600003) 综资同步到无线资源,正在同步当前网元【{}】,异常错误信息【{}】", 
                                syncNetEleType, e.getMessage());
                        e.printStackTrace();
                    }

                    if (!ObjectUtils.isNullObj(resultMap) && !resultMap.isEmpty()) {
                        succCnt += resultMap.get("succCnt");
//                        updateCnt += resultMap.get("updateCnt");
                        excludeCnt += resultMap.get("excludeCnt");
                        succFailCnt += resultMap.get("succFailCnt");
//                        updateFailCnt += resultMap.get("updateFailCnt");
                    }
                }
/**
     * 按批次号同步指定类型网元(多线程异步处理)
     *
     * @param
     * @return java.util.concurrent.CompletableFuture<java.lang.String>
     * @author liangzhaolin
     * @date 2020/7/28 16:45
     */
//    @Async
//    @Async("syncOneNetEleTypeExecutor")
    @Override
    public CompletableFuture<Map<String, Integer>> syncOneNetEleTypeByBatchNum(Class<?> netEleClass, List<MetaWrFieldMap> metaWrFieldMapList, String netEleType, int batchNum, List<String> netElementNameList, String lastUpdateTime) {

        try {
            long startTime = System.currentTimeMillis();

            // 开始行数
//        int startRow = (batchNum * batchQueryNum) + 1;
            int startRow = (batchNum * BATCH_QUERY_NUM) + 1;
            // 结束行数
//        int endRow = (batchNum + 1) * batchQueryNum;
            int endRow = (batchNum + 1) * BATCH_QUERY_NUM;
            // 处理结果 新增
            int resultAdd = 0;
            //更新
            int resultUpdate = 0;
            //不处理结果
            int resultExclude = 0;

            // 新增成功行数 
            int resultAddFail = 0;
            //不处理条数 Station
            int resultUpdateFail = 0;


            // 排列顺序.0:正序;1:倒序.默认0.
            int sortType = 0;
            List<Map<String, Object>> yrInfoMapList;
            // 获取实体类名称
            String netEleClassName = netEleClass.getSimpleName();
            // 获取对应网元mapper
            mapper = (BaseMapper) SpringUtil.getBean(StringUtils.firstToLowerCase(netEleClassName) + "Mapper");

            // 查询指定行数区间的亿阳综资记录, 指定同步数据
            if (netElementNameList != null && netElementNameList.size() > 0) {
                yrInfoMapList = yyzzService.queryYrIncSyncInfo(netEleType, lastUpdateTime, sortType, startRow, endRow, netElementNameList, null);
            }else{
                yrInfoMapList = yyzzService.queryYrIncSyncInfo(netEleType, lastUpdateTime, sortType, startRow, endRow, null, null);
            }

            if(yrInfoMapList == null || yrInfoMapList.size() <= 0){
                log.info("sync_fail (600004) 综资同步到无线资源,正在同步当前网元【{}】, 查询综资数据为【{}】", 
                        netEleType ,yrInfoMapList);
            }
            log.info("sync_info (500008) 综资同步到无线资源,正在同步当前网元【{}】, 查询综资数据为【{}】", 
                    netEleType ,yrInfoMapList.toString());
            // 遍历每条亿阳综资查询数据进行处理
            for (Map<String, Object> yrInfoMap : yrInfoMapList) {
                log.info("sync_info (500009) 综资同步到无线资源,正在同步当前网元【{}】, 查询综资遍历数据【{}】", netEleType, yrInfoMap);
                try {
                    //当前数据是否存在无线资源库中,如果存在,综资的最后修改时间是否大于无线资源的最后修改时间
                    //大于则修改
                    int saveOrExclude = wrSyncDateUpdateConfirm(yrInfoMap, netEleType);
                    log.info("sync_info (500010) 综资同步到无线资源,正在同步当前网元【{}】, 判断新增或修改 1:需要修改 2:不操作 3:新增 4:不操作【{}】", netEleType, saveOrExclude);
    //                //1:不操作  0:新增
                    if(saveOrExclude == 0){
                        //0:新增  并插入日志
                        resultAdd = syncOneNetEleTypeWithTransaction(netEleClass, netEleType, metaWrFieldMapList, yrInfoMap, saveOrExclude);
                        if(resultAdd == 0){
                            resultAddFail++;
                            log.info("sync_fail (600006) 综资同步到无线资源,正在同步当前网元【{}】, 数据同步新增失败【{}】,新增失败状态【{}】", 
                                    netEleType ,yrInfoMap ,saveOrExclude);
                        }else if(resultAdd == 1){
                            //新增成功把综资id保存到map集合中
                            if("station".equals(netEleType)){
                                gatherStationMap.put(String.valueOf(yrInfoMap.get("空间资源ID")), String.valueOf(yrInfoMap.get("空间资源名称")));
                            }if("room".equals(netEleType)){
                                gatherRoomMap.put(String.valueOf(yrInfoMap.get("空间资源ID")), String.valueOf(yrInfoMap.get("空间资源名称")));
                            }
                            log.info("sync_info (600601) 综资同步到无线资源新增成功,正在同步当前网元【{}】,空间资源ID【{}】,空间资源名称【{}】",
                                    netEleType, String.valueOf(yrInfoMap.get("空间资源ID")), String.valueOf(yrInfoMap.get("空间资源名称")));
                            resultAdd++;
                        }
                    }else if(saveOrExclude == 1){
                        //不处理(不符合新增或修改要求)
                        resultExclude++;
                    }
                } catch (Exception e) {
                    if (e instanceof DuplicateKeyException) {
                        log.info("sync_fail (600007) 综资同步到无线资源,正在同步当前网元【{}】,数据同步新增失败-1【{}】,异常错误信息【{}】",
                                netEleType ,yrInfoMap ,e.getMessage());
                        // do nothing
                        // 如果入库报错(目前估计可能引起入库报错的情况只有,重跑程序时,插入wr_yr_sync_log日志表时会有冲突而引起的报错回滚),do nothing,keep running
                    } else {
                        log.info("sync_fail (600008) 综资同步到无线资源,正在同步当前网元【{}】,数据同步新增失败-2【{}】,异常错误信息【{}】", 
                                netEleType, yrInfoMap, e.getMessage());
                    }
                }
            }

            Map<String, Integer> cfMap = new HashMap<>();
            cfMap.put("succCnt", resultAdd);//处理条数
            cfMap.put("excludeCnt", resultExclude);//不处理条数
            cfMap.put("succFailCnt", resultAddFail);//更新失败条数

            // 返回本批处理的记录成功行数和总行数
            CompletableFuture<Map<String, Integer>> completableFuture = CompletableFuture.completedFuture(cfMap);

            long endTime = System.currentTimeMillis();
    
            log.info("sync_into_test (1100001) 综资同步到无线资源,当前网元同步网元【{}】,同步5000条耗时【{}】毫秒," +
                    "查询分页开始【{}】,查询分页结束【{}】,同步时间范围【{}】", netEleType, endTime - startTime, 
                    startRow, endRow, lastUpdateTime);

            return completableFuture;
        } catch (Exception e) {
            log.info("sync_fail (6100009) 综资同步到无线资源,正在同步当前网元【{}】,异常错误信息【{}】",
                    netEleType, e.getMessage());
            e.printStackTrace();
        }
        
        return null;
    }
@Configuration
@Slf4j
public class ThreadExecutorConfig {

    /**
     * 配置亿阳综资同步无线资源接口线程池
     *
     * @param
     * @return java.util.concurrent.Executor
     * @author liangzhaolin
     * @date 2020/8/2 17:31
     */
    @Bean("yrSyncWrExecutor")
    public Executor yrSyncWrExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        // 核心线程数:线程池创建时候初始化的线程数
        executor.setCorePoolSize(30);
        // 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(300);
        // 缓冲队列:用来缓冲执行任务的队列
        executor.setQueueCapacity(600);
        // 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60);
        // 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
        executor.setThreadNamePrefix("YrSyncWrThread-");
        // 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程),这里是DiscardPolicy丢弃策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());

        executor.initialize();

        return executor;
    }


    /**
     * 配置实时无线同步综资接口线程池
     *
     * @param
     * @return java.util.concurrent.Executor
     * @author linlianghong
     * @date 2020/11/13
     */
    @Bean("realYrSyncWrExecutor")
    public Executor realYrSyncWrExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        // 核心线程数:线程池创建时候初始化的线程数
        executor.setCorePoolSize(10);
        // 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(15);
        // 缓冲队列:用来缓冲执行任务的队列
        executor.setQueueCapacity(600);
        // 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60);
        // 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
        executor.setThreadNamePrefix("RealYrSyncWrThread-");
        // 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程),这里是DiscardPolicy丢弃策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());

        executor.initialize();

        return executor;
    }


    /**
     * 配置线程池
     * ThreadPoolTaskExecutor的处理流程:当池子大小小于corePoolSize,就新建线程,并处理请求
     * 当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去workQueue中取任务并处理
     * 当workQueue放不下任务时,就新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理
     * 当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁
     * 其会优先创建corePoolSize线程,当继续增加线程时,先放入Queue中,当 CorePoolSiz  和 Queue 都满的时候,就增加创建新线程,当线程达到MaxPoolSize的时候,就会抛出错
     * 另外MaxPoolSize的设定如果比系统支持的线程数还要大时,会抛出java.lang.OutOfMemoryError: unable to create new native thread 异常。
     *
     * @author liangzhaolin
     * @date 2020/7/24 14:43
     * @see "https://blog.csdn.net/csdn_pangxiong/article/details/103731613"
     * @see "https://www.jianshu.com/p/14bde4e6f747"
     */
    @Bean("syncOneNetEleTypeExecutor")
    public Executor syncOneNetEleTypeExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        // 核心线程数:线程池创建时候初始化的线程数
        executor.setCorePoolSize(30);
        // 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(300);
        // 缓冲队列:用来缓冲执行任务的队列
        executor.setQueueCapacity(600);
        // 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60);
        // 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
        executor.setThreadNamePrefix("SyncOneNetEleTypeThread-");
        // 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程),这里是DiscardPolicy丢弃策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());

        executor.initialize();

        return executor;
    }
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多线程编程实例(使用CompletableFuture) 的相关文章

  • 计算机视觉——opencv-python

    opencv xff1a question1 10 main contentoriginal materialtrouble shootingq1 通道交换q2 灰度化q3 二值化q3 大津二值化算法 xff08 Otsu 39 s Met
  • 数字一阶低通滤波器simulink仿真

    数字一阶低通滤波器simulink仿真 原理程序所用公式滤波系数计算方法 仿真根据公式搭建使用simulink自带模型 原理 程序所用公式 y n 61 q x n 43 1 q y n 1 其中 xff0c y n 表示当前的输出 xff
  • SDFormat

    http sdformat org
  • putty远程连接不上虚拟机里的linux

    昨天跟着阿铭的视频在虚拟机中搭建了centos6 xff0c 然后用putty远程连接成功 今天中午鼓弄putty 的时候 xff0c 连接就报错了 xff1a network error xff1a connection refuse 网
  • 【ADRC】根据ADRC的思想改进PID

    根据前面两篇关于ADRC的文章以及PID原理的文章 xff0c 我们可以利用ADRC的思想来对PID算法做一些改进来看看效果 xff0c 可以将改进的PID称之为非线性PID 主要可以利用跟踪微分器 xff0c 针对PID的两个缺陷来进行改
  • STM32F1 TCA9548A 驱动多个IIC器件

    TCA9548A的用途就是IIC扩展 xff0c 每个TCA9548A可以扩展出8路IIC TCA9548A芯片带有地址选择引脚A0 A1 A2 xff0c 根据高低电平不同 xff0c 从MCU的一路IIC最多可以接入8个TCA9548A
  • 无限 for 循环的实现【Python】

    for 循环怎么才能无限循环下去呢 xff1f 1 最 low 的方法 xff1a 一个无限的列表 理解 for 在干什么 xff0c 在遍历 xff0c 那我们给他一个无限长的东西 xff0c 不就无限循环了 list span clas
  • VirtualBox 安装增强功能时无工具栏

    最近在学Ros xff0c 老师虚拟机用的是VirtualBox xff0c 在安装增强功能时 xff0c 找不到窗口顶部的工具栏 xff0c 如图 1 1所示 查了不少解决方案 xff0c 总结如下 图 1 1 Virtu alBox虚拟
  • Eigen库中的Identity()函数作用

    今天学习Eigen库 xff0c 看到示例代码中有这样一行 xff1a Matrix3d rotation matrix 61 Matrix3d Identity Matrix3d xff1a Eigen库中typedef的数据类型 xff
  • SLAM十四讲-ch3-vistalizegeometry编译问题

    最近在学高翔博士的 SLAM十四讲 xff0c 在ch3中运行vistalizegeometry这个demo的时候 xff0c 出现如下报错信息 xff08 图片版报错看不清的话 xff0c 文末 附文字版的报错信息 xff09 xff1a
  • C++库fmt缺失导致编译失败的解决方案【SLAM十四讲/ch4】

    最近学习高翔博士的SLAM十四讲 xff0c 学到ch4的时候 xff0c 实际运行demo报错 查看CMakeLists txt xff0c 发现Ubuntu20 04需要额外安装fmt库才可以编译通过 解决方法 xff1a 直接去fmt
  • SLAM十四讲编译全过程记录与错误与解决方案汇总

    章节目录 ch2 ch3 ch4 ch5 ch7 ch8 ch9 ch10 ch11 ch2 编译正常 xff0c log如下 xff1a slambook2 master ch2 mkdir build amp amp cd build
  • ROS安装:一键解决人生烦恼

    首先 xff0c 这个方法不是我发明的 xff0c 详情请见文末链接 不管你是unbuntu 16 18 20 xff0c 不管你是新安装的系统 xff0c 还是ROS装了一部分进行不下去的烂摊子都适用 xff01 直接输入下面这一行代码
  • 【Eigen库使用】角轴、旋转矩阵、欧拉角、四元数转换

    零 前言 在slam中经常用到的四种描述机器人orientation的变量 xff0c 他们之间可以相互转化 xff0c 使用Eigen库可以很容易的做到这一点 xff0c 需要特别关注的是 xff1a 欧拉角与其余量之间的转换关系 xff
  • 【Gazebo/ROS】阿克曼小车仿真环境设置中的心得体会

    最近科研需要在gazebo中做一个阿克曼小车的仿真 xff0c 要求小车运动能够通过话题来控制 xff0c 小车上要安装激光雷达 imu 相机等传感器用于SLAM定位建图 由于是第一次接触gazebo仿真 xff0c 所以分享一下学习心得
  • 【ADRC】自抗扰控制

    在根据前面四篇文章的自抗扰控制各个功能部分的分解介绍以及对于PID算法原理的分析之后 xff0c 具体可以查看我的主页 之后我们可以画出自抗扰控制的框图 xff0c 并作出自抗扰的仿真了 自抗扰的组成部分 ADRC说得更直白一些 xff0c
  • 【磕盐随记】对两种机器人ROS代码结构的思考与总结

    本帖看似短小 xff0c 但是凝结了我这一个月的全部心得体会 xff0c 日后打算专门出一期视频专门说说ros机器人的代码结构和类设计 xff0c 今天先在这里简单记录一下 到目前我接触过两种架构 xff0c 根据多节点式和单节点式 自己发
  • 【磕盐随记】IMU数据的运用——姿态R对时间t求导

    一 前言 IMU能够测量到三轴加速度和角速度 xff0c 那么如何在slam中使用imu测量得到的数据呢 xff1f Fast lio的论文中有很好的演示 xff1a 上述公式中 xff0c 最让我不能理解的就是这个 d R d
  • 【磕盐随记】Nodelet类的简明使用

    前言 一直不太懂ROS的Nodelet xff0c 今天佳爷给我拿他的 Elastic Tracker 作为例子给我讲了一下 xff0c 在此简单记录 xff0c 方便后续使用 一 Nodelet的工作原理 nodelet是用来方便ros的
  • 有功功率、无功功率、视在功率、功率因素

    有功功率 xff08 平均功率 xff09 P 61 UI cos 单位为W xff08 瓦 xff09 U单位V xff08 伏 xff09 xff0c I单位A xff08 安 xff09 无功功率 Q 61 UI sin 单位为Var

随机推荐

  • KEIL 生成bin文件 MDK 51 ram bin 文件

    使用keil做项目开发 xff0c 并且需要做IAP功能时 xff0c 就需生成bin文件 xff0c bin文件相比于hex文件更小 xff0c 一般用 bin文件作为升级文件 keil无法像iar一样通过工程设置直接输出bin文件 xf
  • ADC 采样数据抖动

    MSP430或STM32 xff0c 在使用内部ADC出现的采样数据异常抖动问题 采样设计 xff1a 用于检测供电线路电流及电压 产品运行在两种模式下 xff0c 1 低功耗静态模式 xff08 仓储态 xff09 xff0c 2 全功能
  • CC1310 基于CCS工程建立+Sensor Controller ADC

    基于TIRTOS xff0c PacketTx 43 Sensor Controller ADC 43 CCS工程建立 需要的工具 xff1a 1 simplelink cc13x0 sdk 3 20 00 23 CC1310的SDK xf
  • linux w5500 驱动及使用

    1 驱动 驱动来源 a 内核驱动 xff1b b xff1a 官方驱动 a 内核 xff1a linux内核w5500驱动 xff0c 包含两个源文件w5100 c和w5100 spi c kernel drivers net ethern
  • 扩展 IO pca95555 linux驱动 及使用

    驱动 xff1a 内核驱动 xff1a kernel drivers gpio gpio pca953x c make menuconfig配置编译 或拷贝出来手动编译成模块加载 设备树 xff1a 使用2个芯片 xff0c 在同一i2c总
  • Linux内核崩溃 dump调试

    内核 crash 崩溃 xff0c oops消息 xff0c dump oops xff08 也称 panic xff09 xff0c 称程序运行崩溃 xff0c 程序崩溃后会产生oops消息 应用程序或内核线程的崩溃都会产生oops消息
  • 【路径规划】VFH

    简介 在没有全局地图或者是应对动态障碍物的情况下 xff0c 往往是运用局部规划来进行绕障 xff0c 在局部规划的经典算法中 xff0c 比较常用的是 DWA 与 VFH xff0c VFH 全名向量场直方图算法 xff0c 不同于 DW
  • keil5 编译程序出现错误Error: L6411E: No compatible library exists with a definition of startup symbol __main

    Error L6411E No compatible library exists with a definition of startup symbol main 之前装过ADS xff0c ADS与MDK冲突 xff0c 依据网友提供的
  • LORA 射频自组网 两级中继

    基于sx1276lora模块 xff0c 进行多个模块之间自组网 xff0c 组网形式为1个集中器加多个终端 模块之间距离较远时 xff0c 集中器无法直接与某个终端进行通信 xff0c 其他终端本身可作为中继给该终端作为中继与集中器通信
  • STM32上进行Delay延时的方法

    1 使用SYStick专门的延时 void delay us uint32 t us static uint32 t delay flag 61 0 delay flag 61 1 set reload register HCLK 61 4
  • 内核模块已打开,但开机未加载

    环境 xff1a 系 统 Centos 6 6 内核版本 xff1a linux 2 6 32 1 vmware转qcow2格式 xff0c 内核崩溃 最近做一个kvm的镜像 xff0c 尽力裁小内核大小 xff0c 从VMware格式转q
  • px4飞控校准中常遇到的一些坑

    1 校准中最后给飞控独立供电 xff0c 这样可以避免一些不必要的错误 比如要给飞控解锁 xff0c 就必须是给飞控独立供电 xff0c 不能通过USB线给飞控供电 2 校准时至少给飞控接上数传和GPS xff0c 注意GPS的方向和机头方
  • ros+mavros+gazebo仿真实践要点总结

    1 安装ros时要看好对应的版本 xff0c ubuntu16 4对应的kenitic版本 xff0c Ubuntu18 04对应的melodic版本 2 通过ssh方式clone px4 firmware比http方式快的多 3 参考教程
  • offboard

    GAAS
  • 无人机飞控系统的简单分析

    这里写自定义目录标题 刚上大一的时候的学业报告 xff0c 将就这看吧 无人机控制系统原理的简单分析 摘要 xff1a 无人机 xff08 UAV xff09 是无人驾驶飞机的简称 xff0c 是指利用无线电遥控设备和自备的程序控制装置操纵
  • [网络编程]运用socket实现本地通信

    功能实现 基于socket文件 xff0c 进行数据传递 xff0c 实现服务器与客户端之间进行本地通信 设计思路 服务器 创建socket套接字将socket套接字关联到socket文件 xff0c 实现绑定并创建套接字文件此时 xff0
  • 学东西要先看这个东西能给你提供什么功能,作东西要明白自己要实现什么功能!一定要耐下性子!

    学东西不要急匆匆去学 xff0c 首先要明白你要学的这个东西它能给你提供什么功能 xff0c 然后再去学这些功能怎么应用 xff0c 怎么实现的 xff0c 甚至 xff0c 只去学习自己需要使用的功能 作东西也不要匆匆就去作 xff0c
  • Linux系统 搭建gitlab仓库服务器

    安装依赖工具 安装技术依赖 yum span class token function install span y span class token function curl span policycoreutils python op
  • chmod +x 与chmod +777的区别

    对于chmod 43 x 脚本 来说就是将脚本改为可执行状态 xff0c 在linux因高亮语法 xff0c 会让file文件显示加黑 对于灰色的文件来说 xff0c 没有可执行的权限 xff0c 这是若我们给它chmod 43 x后它将会
  • 多线程编程实例(使用CompletableFuture)

    关键配置 xff1a 代理类对象 YrSyncWrService yrSyncWrServiceProxy 获取代理类的对象 xff0c 调用本类方法时 xff0c 注解才会生效 比如 64 Async多线程 xff0c 64 Transa