Activiti7_使用

news/2024/7/20 17:13:28/文章来源:https://blog.csdn.net/Q95470/article/details/139230085

Activiti7_使用

  • 一、Activiti7
  • 二、绘制工作流
  • 三、通过代码部署流程,再对流程进行实例化,完整运行一遍流程即可
  • 四、在springbooot中使用


一、Activiti7

  1. 为了实现后端的咨询流转功能,学习Activiti7,记录下使用的过程及遇到的问题

二、绘制工作流

  1. 使用spring3的后端项目为基础,开发工具idea 2023.3.2,jdk,jdk17。
    点此链接link去idea官网下载插件Activiti BPMN,在idea的Settings里Plugins使用install plugin from disk把刚才的jar包导进去
  2. 在bpmn文件夹下创建bpmn文件:
    !在这里插入图片描述
  3. 使用插件以画图形式编辑bpmn:
    在这里插入图片描述
    主要使用了三种部件:开始、任务、结束在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
任务的内容填写如下,连线按住右上角的箭头拖拽到目标即可,里面的${user}表明设置为user的变量,一会可以在使用的时候绑定用户:
在这里插入图片描述
其中的分支路线我们直接使用两个互斥条件判断,不使用排他网关:
在这里插入图片描述在这里插入图片描述

排他网关(也叫异或(XOR)网关,或叫基于数据的排他网关),用来在流程中实现决策。 当流程执行到这个网关,所有分支都会判断条件是否为 true,如果为 true 则执行该分支,注意,排他网关只会选择一个为 true 的分支执行。 (即使有两个分支条件都为 true, 排他网关也会只选择一条分支去执行)。如果从网关出去的线所有条件都不满足则系统抛出异常。说明 :经过排他网关必须要有一条且只有一条分支走。
bpmn文件绘制完成了,保存成同名png文件:在这里插入图片描述

  1. 完整的bpmn代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef"><process id="consult" name="consult" isExecutable="true"><startEvent id="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1"/><userTask id="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4" name="用户填写咨询表单" activiti:assignee="${user}"><documentation>用户填写咨询表单</documentation></userTask><userTask id="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854" name="管理员指定业务人员" activiti:assignee="${admin}"><documentation>管理员指定业务人员</documentation></userTask><userTask id="sid-7b539102-6d65-479a-9958-5259a84c28b1" name="业务人员回复" activiti:assignee="${busPerson}"><documentation>业务人员回复</documentation></userTask><userTask id="sid-3af84618-4ba9-4686-a97f-6db4da96e916" name="管理员决定是否公示" activiti:assignee="${admin}"><documentation>管理员决定是否公示</documentation></userTask><endEvent id="sid-bd329163-e466-4ca7-bad1-9b95787e28a6"/><sequenceFlow id="sid-c2da4d94-8eac-4acd-9cb0-16328237a136" sourceRef="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1" targetRef="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4"/><sequenceFlow id="sid-5be6635f-b5ef-4e0e-98af-1b35c6e085ae" sourceRef="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4" targetRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854"/><sequenceFlow id="sid-5dc1e8b5-e2bc-45b7-b559-bffe2d3b5c24" sourceRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854" targetRef="sid-7b539102-6d65-479a-9958-5259a84c28b1"/><sequenceFlow id="sid-c3c3594c-d7d1-462f-b057-59b12dbeb190" sourceRef="sid-3af84618-4ba9-4686-a97f-6db4da96e916" targetRef="sid-bd329163-e466-4ca7-bad1-9b95787e28a6"/><sequenceFlow id="sid-8a860827-e9ad-4c62-b931-939d312ddcd8" sourceRef="sid-7b539102-6d65-479a-9958-5259a84c28b1" targetRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854"><conditionExpression>${evection.num&gt;1}</conditionExpression></sequenceFlow><sequenceFlow id="sid-f4dc4277-d16a-415e-9cac-fe51d1c6ee65" sourceRef="sid-7b539102-6d65-479a-9958-5259a84c28b1" targetRef="sid-3af84618-4ba9-4686-a97f-6db4da96e916"><conditionExpression>${evection.num&lt;=1}</conditionExpression></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_consult"><bpmndi:BPMNPlane bpmnElement="consult" id="BPMNPlane_consult"><bpmndi:BPMNShape id="shape-b1791cfb-c3c9-42a9-9bd8-b7e0a8906f99" bpmnElement="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1"><omgdc:Bounds x="-15.0" y="-120.0" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-33324ea7-5905-4b2a-b615-2bfe666a0117" bpmnElement="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4"><omgdc:Bounds x="-50.0" y="-60.0" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-955afe5f-f9b7-40f0-887f-70aeb5afc173" bpmnElement="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854"><omgdc:Bounds x="-50.0" y="40.0" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-7a2e9e19-c268-4a46-af9c-aa6621dd9b86" bpmnElement="sid-7b539102-6d65-479a-9958-5259a84c28b1"><omgdc:Bounds x="-50.0" y="150.0" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-86aead71-8e5b-4de3-8d8c-ca5f0dcc63ea" bpmnElement="sid-3af84618-4ba9-4686-a97f-6db4da96e916"><omgdc:Bounds x="-50.0" y="255.0" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-1d13b250-9f5c-42db-a745-482b2c9acf56" bpmnElement="sid-bd329163-e466-4ca7-bad1-9b95787e28a6"><omgdc:Bounds x="-15.0" y="360.0" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-c60fd374-56ca-4630-9f88-c9d61baa048b" bpmnElement="sid-c2da4d94-8eac-4acd-9cb0-16328237a136"><omgdi:waypoint x="0.0" y="-90.0"/><omgdi:waypoint x="0.0" y="-60.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-4a1da47a-a9b5-4db2-a8a9-002220e5c52a" bpmnElement="sid-5be6635f-b5ef-4e0e-98af-1b35c6e085ae"><omgdi:waypoint x="0.0" y="20.0"/><omgdi:waypoint x="0.0" y="40.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-3d9c4ead-a6cd-4aa2-82c7-ad1f20171327" bpmnElement="sid-5dc1e8b5-e2bc-45b7-b559-bffe2d3b5c24"><omgdi:waypoint x="0.0" y="120.0"/><omgdi:waypoint x="0.0" y="150.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-2116f8bb-51a7-4c43-a48b-7c4954868724" bpmnElement="sid-c3c3594c-d7d1-462f-b057-59b12dbeb190"><omgdi:waypoint x="0.0" y="335.0"/><omgdi:waypoint x="0.0" y="360.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-ce0e6fc3-032f-4333-83ec-7807846b046f" bpmnElement="sid-8a860827-e9ad-4c62-b931-939d312ddcd8"><omgdi:waypoint x="-50.0" y="190.0"/><omgdi:waypoint x="-125.0" y="135.0"/><omgdi:waypoint x="-50.0" y="80.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-87fa2036-1930-4551-bede-92f275696c68" bpmnElement="sid-f4dc4277-d16a-415e-9cac-fe51d1c6ee65"><omgdi:waypoint x="0.0" y="230.0"/><omgdi:waypoint x="0.0" y="242.5"/><omgdi:waypoint x="0.0" y="255.0"/></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>

三、通过代码部署流程,再对流程进行实例化,完整运行一遍流程即可

需要序列化一个evection:在这里插入图片描述

package com.sumo.ipd;import java.io.Serializable;public class Evection implements Serializable {public int getNum() {return num;}public void setNum(int num) {this.num = num;}private int num;
}

在test里面创建ActivitiDemo类,内容:

package com.sumo.ipd;import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ActivitiDemo {/*** 部署流程定义测试,查询,删除*/@Testpublic void DeployTest() {// 1. 创建ProcessEngine流程引擎对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2、得到RepositoryService实例RepositoryService repositoryService = processEngine.getRepositoryService();// 3、使用RepositoryService进行部署,定义一个流程名字,把bpmn和png部署到数据库中Deployment deployment = repositoryService.createDeployment()    // 创建一个部署流程.name("咨询流程")                                    // 给部署流程命名.addClasspathResource("bpmn/consult.bpmn20.xml")        // 添加类路径下的资源文件.addClasspathResource("bpmn/consult.png").deploy();                                                // 执行流程部署// 4、输出部署信息System.out.println("流程部署id:" + deployment.getId());System.out.println("流程部署名称:" + deployment.getName());}@Testpublic void queryProceccDefinition() {// 流程定义keyString processDefinitionKey = "consult";// 创建ProcessEngine流程引擎对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 获取repositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();// 查询流程定义ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();//遍历查询结果List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey(processDefinitionKey).orderByProcessDefinitionVersion().desc().list();for (ProcessDefinition processDefinition : list) {System.out.println("------------------------");System.out.println(" 流 程 部 署 id : " +processDefinition.getDeploymentId());System.out.println("流程定义id: " + processDefinition.getId());System.out.println("流程定义名称: " + processDefinition.getName());System.out.println("流程定义key: " + processDefinition.getKey());System.out.println("流程定义版本: " + processDefinition.getVersion());}}@Testpublic void deleteDeployment() {// 流程部署idString deploymentId = "47501";// 通过流程引擎获取repositoryServiceProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();
//        删除启动的流程实例RuntimeService runtimeService = processEngine.getRuntimeService();runtimeService.deleteProcessInstance("50001","用户撤销");//删除流程定义, 如果该流程定义已有流程实例启动则删除时出错//repositoryService.deleteDeployment(deploymentId);//设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设//置为false非级别删除方式,如果流程repositoryService.deleteDeployment(deploymentId, true);}/*** 启动流程实例*/@Testpublic void startProcessTest() {//businessKey用于绑定外部任务表单的idString businessKey = "1";// 1、创建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2、获取RunTimeServiceRuntimeService runtimeService = processEngine.getRuntimeService();// 流程变量的mapMap<String, Object> variables = new HashMap<>();// 设定任务的负责人variables.put("user", "523097198902120431");variables.put("admin", "123456");variables.put("busPerson", "123456789");Evection evection = new Evection();evection.setNum(3);// 把流程变量的pojo放入mapvariables.put("evection",evection);// 3、根据流程定义Id启动流程,并获取流程实例ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("consult", businessKey, variables);// 输出内容System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());System.out.println("流程实例id:" + processInstance.getId());System.out.println("当前活动Id:" + processInstance.getActivityId());System.out.println("businessKey==" + processInstance.getBusinessKey());}/*** 查询当前个人待执行的任务*/public void findTaskListTest(String assignee) {// 1.创建流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2.获取TaskServiceTaskService taskService = processEngine.getTaskService();// 3.根据流程key 和 任务负责人 查询任务List<Task> list = taskService.createTaskQuery().processDefinitionKey("consult")        //流程Key.taskAssignee(assignee)                    //只查询当前任务负责人的任务.list();Task task = taskService.createTaskQuery()
//                .processInstanceId("15001")            //流程实例id.processDefinitionKey("consult")     //流程Key.taskAssignee(assignee)                 //只查询当前任务负责人的任务.singleResult();String processInstanceId = task.getProcessInstanceId();// 2、获取RunTimeServiceRuntimeService runtimeService = processEngine.getRuntimeService();ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();String businessKey = processInstance.getBusinessKey();//        list.forEach(task -> {System.out.println("-----------------------------------------");System.out.println("流程实例id:" + task.getProcessInstanceId());System.out.println("任务id:" + task.getId());System.out.println("任务负责人:" + task.getAssignee());System.out.println("任务名称:" + task.getName());System.out.println("businessKey==" + businessKey);
//        });Evection eve = (Evection)taskService.getVariable(task.getId(), "evection");System.out.println(eve.getNum());System.out.println("获取流程变量成功");}/*** 完成个人代办任务及查询下一步*/@Testpublic void completTaskTest() {findTaskListTest("523097198902120431");completTask("523097198902120431");findTaskListTest("123456");completTask2("123456");findTaskListTest("123456789");completTask("123456789");findTaskListTest("123456");completTask("123456");}/*** 普通的完成任务* @param assignee*/public void completTask(String assignee) {// 1.创建流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2. 获取TaskService实例TaskService taskService = processEngine.getTaskService();// 3.根据流程key 和 任务的负责人 查询任务Task task = taskService.createTaskQuery().processDefinitionKey("consult")     //流程Key.taskAssignee(assignee)                 //只查询当前任务负责人的任务.singleResult();System.out.println("流程实例id:" + task.getProcessInstanceId());System.out.println("任务id:" + task.getId());System.out.println("任务负责人:" + task.getAssignee());System.out.println("任务名称:" + task.getName()+" 完成!");// 4.完成待办任务,参数:任务idtaskService.complete(task.getId());}/*** 在完成任务时修改变量调整分支走向* @param assignee*/public void completTask2(String assignee) {// 1.创建流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2. 获取TaskService实例TaskService taskService = processEngine.getTaskService();// 3.根据流程key 和 任务的负责人 查询任务Task task = taskService.createTaskQuery().processDefinitionKey("consult")     //流程Key.taskAssignee(assignee)                 //只查询当前任务负责人的任务.singleResult();System.out.println("流程实例id:" + task.getProcessInstanceId());System.out.println("任务id:" + task.getId());System.out.println("任务负责人:" + task.getAssignee());System.out.println("任务名称:" + task.getName()+" 完成!");// 流程变量的mapMap<String, Object> variables = new HashMap<>();Evection evection = new Evection();evection.setNum(1);// 把流程变量的pojo放入mapvariables.put("evection",evection);// 4.完成待办任务,参数:任务idtaskService.complete(task.getId(),variables);}/*** 如果一个流程中有多个任务,可以用list*/@Testpublic void completeTask3() {// 获取引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 获取操作任务的服务 TaskServiceTaskService taskService = processEngine.getTaskService();// 完成 经理 '李四' 的任务List<Task> tasks = taskService.createTaskQuery().processDefinitionKey("evection").taskAssignee("李四").list();  // 多个任务,用listfor (Task task : tasks) {if (true) {// 判断是哪任务System.out.println("流程实例id=" + task.getProcessInstanceId());System.out.println("任务Id=" + task.getId());System.out.println("任务负责人=" + task.getAssignee());System.out.println("任务名称=" + task.getName());taskService.complete(task.getId());}}}
}

运行ActivitiDemo完整运行一遍流程:
1DeployTest部署流程
2startProcessTest启动流程实例
3completTaskTest运行一遍流程

四、在springbooot中使用

依赖会出现报错,需要修改pom.xml

  1. 使用log4j会和springboot本身的logback冲突,排除logback
		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><artifactId>spring-boot-starter-logging</artifactId><groupId>org.springframework.boot</groupId></exclusion></exclusions></dependency>
  1. 已经有mybatis了,把不用的注释掉在这里插入图片描述

  2. 排除slf4j-log4j12的log4j,避免和外面的log4j冲突

		<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${slf4j.version}</version><exclusions><!-- 排除slf4j-log4j12的log4j,避免和外面的log4j冲突 --><exclusion><artifactId>log4j</artifactId><groupId>log4j</groupId></exclusion></exclusions></dependency>

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

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

相关文章

小牛翻译:图片翻译API+语音翻译API调用,保姆级使用教程

一、小牛翻译接口简介 图片翻译API 支持格式&#xff1a;png、jpg、jpeg、bmp支持图片尺寸&#xff1a;128px*128px~2048px*2048px支持最大图片大小&#xff1a;10M支持的语种&#xff1a;中、英、日、韩、俄 语音翻译API 支持格式&#xff1a;MP3、WAV支持语音时长&#x…

根据经纬度点计算经纬度点之间的距离

根据经纬度点计算经纬度点之间的距离 根据两点经纬度坐标计算直线距离 根据经纬度点计算经纬度点之间的距离 根据经纬度计算两地之间的距离 根据两点经纬度坐标计算距离 其实看第一个就够了 根据 半正矢公式&#xff08;Haversine formula&#xff09;即可计算 本计算式选取地…

2024电激世界脉动-中国汽车品牌全球化制胜手册

来源&#xff1a;奥美Ogilvy&#xff1a; 近期历史回顾&#xff1a; 2024中国宏观经济专题报告-数据要素市场建设 2023-2024年度报告.pdf 2024制药与生化医疗技术产业链白皮书.pdf 从可再生能源到绿氢-中国投资助力埃及能源转型.pdf 2024有机旅行中国行业指引.pdf 2024中国技术…

【常用的队列总结】

文章目录 队列的介绍Queue队列的基本概念与操作队列的基本概念 常见的队列介绍非阻塞队列LinkedList:ArrayDeque:PriorityQueue: 阻塞队列ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueue DelayQueueSynchronousQueue 队列的介绍 Queue队列的基本概念与操作 在 …

常见算法(1)

1.基本查找/顺序查找 核心&#xff1a;从0索引之后挨个查找 实现代码&#xff1a; public class test {public static void main(String [] arg) throws ParseException {int[] arr {121,85,46,15,55,77,63,49};int number55;System.out.println(bashi(arr,number));}publi…

多线程基本常识

多线程的状态 在Java中&#xff0c;一个线程的生命周期有以下几种状态&#xff1a; 新建&#xff08;New&#xff09;&#xff1a;当线程对象被创建时&#xff0c;线程处于新建状态。此时线程对象存在&#xff0c;但还没有调用start()方法启动线程。 运行&#xff08;Runnable…

ssm145基于java的电脑硬件库存管理系统+jsp

电脑硬件库存管理系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对电脑硬件库存信息管理混乱&…

SQL 语言:完整性约束

文章目录 概述主键 ( Primary Key ) 约束外键&#xff08;Foreign Key&#xff09;约束属性值上的约束全局约束总结 概述 数据库的完整性是指数据库正确性和相容性&#xff0c;是防止合法用户使用数据库时向数据库加入不符合语义的数据。保证数据库中数据是正确的&#xff0c;…

React18 apexcharts数据可视化之甜甜圈图

03 甜甜圈图 apexcharts数据可视化之甜甜圈图。 有完整配套的Python后端代码。 本教程主要会介绍如下图形绘制方式&#xff1a; 基本甜甜圈图个性图案的甜甜圈图渐变色的甜甜圈图 面包圈 import ApexChart from react-apexcharts;export function DonutUpdate() {// 数据…

通过扩展指令增强基于覆盖引导的模糊测试

本文由Bruno Oliveira于2024年4月25日发表于IncludeSec的官方网站上。作为IncludeSec的安全研究人员&#xff0c;在他们日常的安全审计和渗透测试工作中&#xff0c;有时需要为客户开发一些模糊测试工具。在安全评估方法中使用模糊测试技术&#xff0c;可以有效地在复杂的现代化…

已解决SyntaxError: EOL while scanning string literal 亲测有效!!!

已解决SyntaxError: EOL while scanning string literal 亲测有效&#xff01;&#xff01;&#xff01; 亲测有效 报错问题解决思路解决方法 报错问题 当你在编写Python代码时&#xff0c;可能会遇到以下报错信息&#xff1a; SyntaxError: EOL while scanning string liter…

如何搭建springBoot项目中的全局异常处理和自定义异常处理

目录 1 什么是异常 2 异常的种类 3 解决异常的方式 4 全局异常处理器和自定义异常处理器 5 测试异常处理 1 什么是异常 异常&#xff08;Exception&#xff09;是在程序执行过程中出现的一种特殊情况或错误。它可以是由于程序逻辑错误、运行环境问题、用户输入错误等原因…

JUC框架-并发容器源码详解

文章目录 并发容器ConcurrentHashMapJDK 1.7 及之前的实现原理JDK 1.8 及之后的实现原理 CopyOnWriteArrayList & CopyOnWriteArraySet工作原理&#xff08;附源码&#xff09;特点适用场景 ConcurrentLinkedQueue数据结构入队列操作ConcurrentLinkedQueue 特性ConcurrentL…

LED屏控制卡是如何控制LED屏的?

LED屏控制卡是LED显示屏的关键组件之一&#xff0c;负责将输入的画面信息转换为LED屏能够显示的数据和控制信号。以下是LED屏控制卡的工作原理和功能的详细介绍&#xff1a; 1. LED显示屏控制器概述&#xff1a; LED显示屏控制器是LED显示屏的核心部件之一&#xff0c;也称为LE…

剪画小程序:自媒体创作的第一步:如何将视频中的文案提取出来?

自媒体创作第一步&#xff0c;文案提取无疑是至关重要的一环。 做自媒体之所以要进行文案提取&#xff0c;有以下重要原因&#xff1a; 首先&#xff0c;提高效率。通过文案提取&#xff0c;可以快速获取关键信息&#xff0c;避免在无关紧要的内容上浪费时间&#xff0c;从而…

685. 冗余连接 II

685. 冗余连接 II 问题描述 在本问题中&#xff0c;有根树指满足以下条件的 有向 图。该树只有一个根节点&#xff0c;所有其他节点都是该根节点的后继。该树除了根节点之外的每一个节点都有且只有一个父节点&#xff0c;而根节点没有父节点。 输入一个有向图&#xff0c;该…

如何将Windows PC变成Wi-Fi热点?这里提供详细步骤

序言 Windows 10和Windows 11都有内置功能,可以将你的笔记本电脑(或台式机)变成无线热点,允许其他设备连接到它并共享你的互联网连接。以下是操作指南。 由于Windows中隐藏的虚拟Wi-Fi适配器功能,你甚至可以在连接到另一个Wi-Fi网络或无线路由器时创建Wi-Fi热点,通过另…

Qt | QTabBar 类(选项卡栏)

01、上节回顾 Qt | QStackedLayout 类(分组布局或栈布局)、QStackedWidget02、简介 1、QTabBar类直接继承自 QWidget。该类提供了一个选项卡栏,该类仅提供了一个选项卡, 并没有为每个选项卡提供相应的页面,因此要使选项卡栏实际可用,需要自行为每个选项卡设置需要显示的页…

基础—SQL—DML(数据操作语言)插入数据

一、介绍 分类全称说明DMLData Manipulation Language数据操作语言。用来对数据库表中的数据进行增删改(插入、删除、修改) 则增、删、改是三个操作也就对应着三个关键字&#xff0c;分别是&#xff1a; 添加数据&#xff1a;&#xff08; INSERT &#xff09;修改数据&#…

远程户外监控组网方案,工业4G路由器ZR2000

户外监控无人值守4G工业路由器组网应用涉及工业自动化、数据传输和远程监控的重要领域。在户外没有光纤的情况下&#xff0c;想要让监控或传感器等设备联网&#xff0c;仅需一台4G工业路由器即可解决。以下是关于远程监控户外组网的详细分析与应用&#xff1a; 物联网应用场景 …