线程的常见使用方法
Java中的线程并不是真正意义的线程,我们使用的是Thread类来表示线程,而这个类是 JVM 用来管理线程的一个类,也就是说,每个线程都有一个唯一的 Thread对象 与之关联
每一个执行流都需要有一个对象来进行描述,那么一个Thread对象就是用来表述一个线程执行流的,JVM会将这些对象统一起来管理,方便线程调度
常见构造方法
方法 | 说明 |
Thread() | 直接创建线程对象 |
Thread(Runnable target) | 使用Runnable对象只创建线程 |
Thread(String name) | 创建线程对象,同时命名 |
Thread(Runnable target,String name) | 使用Runnable对象创建线程,同时命名 |
Thread(()->{代码块}) | 使用lambda表达式创建线程 |
Thread(()->{代码块},String name) | 使用lambda表达式创建线程,同时命名 |
Thread(ThreadGroup group,Runnable target) 仅了解 | 线程可以被用来进行分组管理,分好的组就是线程组 |
//创建线程对象
Thread t = new Thread();
Thread t = new Thread("自定义线程");
//使用Runnable对象
Thread t = new Thread(new Runnable());
Thread t = new Thread(new Runnable("自定义线程"));
//使用lambda表达式
Thread t = new Thread(()->{//代码块
},"自定义线程");
常见属性
属性 | 说明 | 获取方法 |
ID | 线程的唯一标识,不同线程不会重复 | getId() |
名称 | 调用线程的工具的名称 | getName() |
状态 | 线程当前所处的情况 | getState() |
优先级 | 越优先的线程越容易被调用到 | getPriority() |
是否后台线程 | JVM只有在一个进程的所有非后台线程结束后,才会结束运行(只管非后台) | isDaemon() |
是否存活 | 线程是否结束了 | isAlive() |
是否被中断 | isInterrupted() |
public static void main(String[] args) {Thread t = new Thread(()->{for (int i = 0; i < 5; i++) {System.out.println("still alive!");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("I'm going to die");});System.out.println(t.getName()+" ID: "+t.getId());System.out.println(t.getName()+" 状态: "+t.getState());System.out.println(t.getName()+" 优先级: "+t.getPriority());System.out.println(t.getName()+" 后台: "+t.isDaemon());System.out.println(t.getName()+" 存活: "+t.isAlive());System.out.println(t.getName()+" 中断: "+t.isInterrupted());t.start();System.out.println("die? --> 100%");System.out.println(t.getName()+" 状态: "+t.getState());
}
在这个代码中,因为没有设置,t线程就是前台线程
线程启动
使用 start() 方法来启动线程
当我们覆写 run 方法来创建对象时,并不是说明线程开始运行了,这只能说明线程已经创建好了,至于让他动起来,就需要在加其他的方法
例如:
我们去医院进行挂号,当你在挂号处拿到号时,并不代表你可以去医生的诊室就诊了,你只是有了可以就诊的条件
只有当医院播报到你的名字,你才可以去到诊室进行就诊
那么我们覆写run方法创建对象就相当于挂号,而调用start方法就是患者被叫号了
需要注意的一点是,同一进程内,对于同一线程是不可以调用两次start方法的,就像同一患者不会在同种状态下被叫两次(复诊不算-->状态改变了)
public static void main(String[] args) {Thread t = new Thread(()->{for (int i = 0; i < 5; i++) {System.out.println(i);}});t.start();System.out.println("================");t.start();
}
休眠当前线程
线程的调度是不可以控制的,就像上一张图片,是先打印分割符才打印的数字(理想是先打印数字,再打印分割符)所以会用一些方法来保证实际休眠的时间大于等于参数设置的休眠时间
方法 | 说明 |
Public static void sleep(long mills) throws InterruptedException | 休眠当前线程mills毫秒 |
Public static void sleep(long mills,int nanos) throws InterruptedException | 可以更高精度的休眠 |
public static void main(String[] args) throws InterruptedException {System.out.println(System.currentTimeMillis());Thread.sleep(2000);System.out.println(System.currentTimeMillis());
}
获取当前运行线程
方法 | 说明 |
Public static Thread currentThread() | 返回当前线程对象的引用 |
public static void main(String[] args) {Thread t = Thread.currentThread();System.out.println(t.getName());
}
中断线程
当线程开始运行的时候,在线程完成之前是不会结束的!但是我们也可以增加一些机制,用来结束线程,例如你在付款时,突然不想要那个东西了,就会退出付款界面,取消订单,那么此时你的购买操作就被中断了
目前有两种实现中断的方式:
-
通过共享的标记来进行沟通
-
调用interrupt()方法来通知
方法一
使用自定义的变量来作为标志位,需要给标志位加上volatile关键字
public static Boolean isRunning=true;
public static void main(String[] args){Thread t = new Thread(()->{//这里是t线程的条件while (isRunning){//内部类访问外部类的成员System.out.println("thread");try{Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}}System.out.println("t线程结束!");});//t的内部条件在执行时,外部的代码也在一起运行t.start();try {Thread.sleep(3000);//-->过了3s之后 线程修改?}catch (InterruptedException e){e.printStackTrace();}//3秒之后,主线程修改isRunning的值,从而通知 t 结束-->所以会打印3s的threadSystem.out.println("控制t线程结束!");isRunning=false;
}
方法二
使用 Thread.interrupt() 或者 Thread.currentThread().isInterrupted() 代替自定义标志位
方法 | 说明 |
public void interrupt() | 中断与对象关联的线程。如果线程正在阻塞,则以异常方式通知;否则,设置中断标志位 |
public static boolean interrupted() | 判断当前线程的中断标志位是否被设置,并在调用后清除标志位 |
public boolean isInterrupted() | 判断与对象关联的线程的中断标志位是否被设置,调用后不清除标志位 |
public static void main(String[] args) {Thread t =new Thread(()->{while(!Thread.currentThread().isInterrupted()){//Thread.currentThread().isInterrupted() 默认是false//括号内 true是线程要终止了 false线程要继续执行System.out.println("thread");try{Thread.sleep(1000);}catch (InterruptedException e){//e.printStackTrace();throw new RuntimeException(e);//e.printStackTrace();-->会继续执行}}
});t.start();try{Thread.sleep(3000);}catch (InterruptedException e){throw new RuntimeException(e);}t.interrupt();//通过这个方法,相当于设置Boolean值为true-->还能唤醒sleep等阻塞的方法//抛出异常,不会等待
}
Thread 收到的方法有两种:
-
当线程调用 wait/join/sleep 等方法阻塞,使用 InterruptedException 异常的形式通知,清除中断标志
-
此时要不要结束线程取决于catch中的写法,可以报错,可以直接退出等
-
-
设置中断标识
-
Thread.isInterrupted() 判断当前线程的中断标志被设置,清除中断标志
-
Thread.currentThread().isInterrupted() 判断当前线程的中断标志被设置,不清除中断标志
-
等待线程
当我们需要等待一个线程完成之后,其他线程才能继续工作,这个时候我们就要让其他线程等待那个线程,比如当你选好商品打算付款时,发现钱包里面钱不够,你就只能等工资到账之后才能付款,那么此时就是你的付款操作等待工资到账操作
调用 join 方法的线程会让其他线程等待自己完成
public static void main(String[] args) throws InterruptedException {Runnable init = ()->{for (int i = 0; i <5 ; i++) {System.out.println(Thread.currentThread().getName()+"say: I'm running!");}System.out.println("I'm over!");};Thread t1 = new Thread(init,"工资");Thread t2 = new Thread(init,"结账");t1.start();t1.join();System.out.println("工资到账啦!可以买东西了!");t2.start();t2.join();System.out.println("买到喜欢的东西了!");
}
相关文章:
线程的常见使用方法
Java中的线程并不是真正意义的线程,我们使用的是Thread类来表示线程,而这个类是 JVM 用来管理线程的一个类,也就是说,每个线程都有一个唯一的 Thread对象 与之关联 每一个执行流都需要有一个对象来进行描述,那么一个Thread对象就是用来表述一个线程执行流的,JVM会将这些对象统…...
架构师面试(十一):消息收发
问题 IM 是互联网中非常典型的独立的系统,麻雀虽小但五脏俱全,非常值得深入研究和探讨,继上次IM相关题目之后,我们继续讨论IM相关话题。 关于IM系统【消息收发模型】的相关描述,下面说法错误的有哪几项? …...
MoonSharp 文档一
目录 1.Getting Started 步骤1:在 IDE 中引入 MoonSharp 步骤2:引入命名空间 步骤3:调用脚本 步骤4:运行代码 2.Keeping a Script around 步骤1:复现前教程所有操作 步骤2:改为创建Script对象 步骤…...
【linux网络编程】端口
一、端口(Port)概述 在计算机网络中,端口(Port) 是用来标识不同进程或服务的逻辑通信端点。它类似于一座大楼的房间号,帮助操作系统和网络协议区分不同的应用程序,以便正确地传输数据。 1. 端口…...
Vulnhub-Node
目录标题 一、靶机搭建二、信息收集靶机信息扫ip扫开放端口和版本服务信息指纹探测目录扫描 三、Web渗透信息收集zip爆破ssh连接 四、提权内核版本提权 利用信息收集拿到路径得到账户密码,下载备份文件,base64解密后,利用fcrackzip爆破zip压缩…...
RK3568平台(camera篇)camera3_profiles_rk3588.xml解析
camera3_profiles_rk3588.xml 是一个与 Android 相机 HAL(硬件抽象层)相关的配置文件,通常用于定义 Rockchip RK3588 平台上的相机设备及其功能。该文件基于 Android 的 Camera3 HAL 框架,用于描述相机的配置、流配置、分辨率、帧率、格式等信息。 以下是对 camera3_profi…...
高阶哈希算法
SHA-256简介 SHA-256 是 **SHA-2(Secure Hash Algorithm 2)**家族中的一种哈希算法,由美国国家安全局设计,并于 2001 年发布。它能够将任意长度的数据映射为一个固定长度256 位,即 32 字节的哈希值,通常以…...
Spark数据倾斜深度解析与实战解决方案
Spark数据倾斜深度解析与实战解决方案 一、数据倾斜的本质与影响 数据倾斜是分布式计算中因数据分布不均导致的性能瓶颈现象。当某些Key对应的数据量远超其他Key时,这些"热点Key"所在的Task会消耗80%以上的计算时间,成为整个作业的木桶短板。具体表现为: Task执…...
Kubernetes滚动更新实践
前言 在我之前的项目中,对微服务升级采用的做法是删除整个namespace, 再重新应用所有yaml。 这种方式简单粗暴,但是不可避免的导致服务中断,影响了用户体验 为了解决更新服务导致的服务中断问题, Kubernetes提供了一种…...
Broken pipe
比较常见的一个问题。 但是并不是每个人都能说清楚。 首先注意下写法: Broken pipe # B大写 p小写 主要是grep的时候别写错了 常见的原因 1、客户端关闭连接。 在服务器端处理请求的过程中,客户端突然关闭了连接,例如浏览器关闭、网络断开…...
doris:ClickHouse
Doris JDBC Catalog 支持通过标准 JDBC 接口连接 ClickHouse 数据库。本文档介绍如何配置 ClickHouse 数据库连接。 使用须知 要连接到 ClickHouse 数据库,您需要 ClickHouse 23.x 或更高版本 (低于此版本未经充分测试)。 ClickHouse 数据库的 JDBC 驱动程序&a…...
前K个高频单词
692. 前K个高频单词 - 力扣(LeetCode) 题目描述: 给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序…...
恢复IDEA的Load Maven Changes按钮
写代码的时候不知道点到什么东西了,pom文件上的这个弹窗就是不出来了,重启IDEA,reset windos都没用,网上搜也没收到解决方案 然后开打开其他项目窗口时,看到那个的功能名叫 Hide This Notification 于是跑到Setting里…...
【五.LangChain技术与应用】【31.LangChain ReAct Agent:反应式智能代理的实现】
一、ReAct Agent是啥?为什么说它比「普通AI」聪明? 想象一下,你让ChatGPT查快递物流,它可能直接编个假单号糊弄你。但换成ReAct Agent,它会先推理(Reasoning)需要调用哪个接口,再行动(Action)查询真实数据——这就是ReAct的核心:让AI学会「动脑子」再动手。 举个真…...
Leetcode 62: 不同路径
Leetcode 62: 不同路径 问题描述: 一个机器人位于一个 (m \times n) 网格的左上角(起始点位于 ((0, 0)))。 机器人每次只能向下或向右移动一步。网格的右下角为终点(位于 ((m-1, n-1)))。 计算机器人从左上角到右下角…...
计算机毕业设计SpringBoot+Vue.js火锅店管理系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Docker Desktop 4.38 安装与配置全流程指南(Windows平台)
一、软件定位与特性 Docker Desktop 是容器化应用开发与部署的一体化工具,支持在本地环境创建、管理和运行Docker容器。4.38版本新增GPU加速支持、WSL 2性能优化和Kubernetes 1.28集群管理功能,适用于微服务开发、CI/CD流水线搭建等场景。 二、安装环境…...
算法系列之广度优先搜索解决妖怪和尚过河问题
在算法学习中,广度优先搜索(BFS)是一种常用的图搜索算法,适用于解决最短路径问题、状态转换问题等。本文将介绍如何利用广度优先搜索解决经典的“妖怪和尚过河问题”。 问题描述 有三个妖怪和三个和尚需要过河。他们只有一条小船…...
【技术白皮书】内功心法 | 第一部分 | IP协议的目的与工作原理(IP地址)
目录 IP协议的介绍IP协议的目的与工作原理IP协议处理过程与信件传递的相似IP协议处理过程与信件传递的区别IP协议中的概念IP数据包IP地址IP地址组成IP地址分类和组成A、B、C三类地址的格式设计特殊类型的IP地址与传统通信地址进行类比IP地址的表示五类IP地址的地址范围IP地址的…...
【Linux】外接硬盘管理
查看外接硬盘信息 连接外接硬盘后,使用以下命令识别设备: lsblk:列出块设备及其挂载点 lsblk示例输出可能显示设备名称如 /dev/sdb。 通过 lsblk -f 可同时显示文件系统类型和 UUID。 fdisk -l:列出所有磁盘的分区信息ÿ…...
【Hadoop】详解Zookeeper选主流程
1. ZooKeeper 的工作原理 Zookeeper 的核心是Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。 为了保证事务的顺序一致性,Zookeeper采用了递增的事务id号(zxid)来标识事务。所有…...
C语言-语法
数据类型 字符串 C中字符串拼接不用+号,直接使用空格。 char* str = "hello" "world"; 换行链接,加上\就不会报错 char* longStr = "00000000000000000000000000000\ 00000000000000000000000000000"; typedef C 语言提供了 typedef …...
Flink Forward Asia 2024 大会 内容整理
一、Flink 2.0:十年磨一剑,开启流计算新纪元 作为 Flink 诞生十周年的重磅更新,Flink 2.0 被定位为“面向未来十年的流计算引擎”,核心目标是解决云原生、AI 融合、存算效率等新时代挑战。以下是它的几大杀手锏: 1. …...
golang进阶知识专项-理解值传递
在 Go 语言中,所有函数的参数传递都是值传递(Pass by Value)。当你将一个变量作为参数传递给函数时,实际上传递的是该变量的副本,而不是变量本身。理解这一点对于避免常见的编程错误至关重要。根据不同的类型ÿ…...
2020年联考《申论》第三题(河北县级卷)
材料: 总面积不过八平方米的店铺,摆满货品之后,两人在店内走动都有些困难,但这家小店在当地却是小有名气的老字号。69岁的店主老林是资深木雕艺人,更被称为“最后的手工酸枝筷子传人”。手工木筷取材自缅甸坤甸木、老挝…...
Kali WebDAV 客户端工具——Cadaver 与 Davtest
1. 工具简介 在 WebDAV 服务器管理和安全测试过程中,Cadaver 和 Davtest 是两款常用的命令行工具。 Cadaver 是一个 Unix/Linux 命令行 WebDAV 客户端,主要用于远程文件管理,支持文件上传、下载、移动、复制、删除等操作。Davtest 则是一款…...
八点八数字科技:开启数字人应用的无限可能
在数字科技飞速发展的时代,八点八数字科技凭借卓越实力,成为行业的领军者。自 2014 年成立,公司汇聚近百位顶尖人才,手握 30 新型发明专利与 80 软件著作权,完成数千万融资,实力备受认可。其自主研发的全…...
Vue 使用 vue-router 时,多级嵌套路由缓存问题处理
Vue 使用 vue-router 时,多级嵌套路由缓存问题处理 对于三级菜单(或多级嵌套路由),vue 都是 通过 keep-alive 组件来实现路由组件的缓存。 有时候三级或者多级路由时,会出现失效情况。以下是三级菜单缓存的例子。 最…...
《实战AI智能体》Deepseek可以做什么?自然语言理解与分析
在人工智能技术快速迭代的今天,Deepseek凭借其先进的自然语言处理能力,正在重塑人机交互的边界。本文将从技术实现维度,深入解析该平台在自然语言理解、知识推理与文本分类三大核心领域的技术突破与应用实践。 一、深度语义理解引擎 Deepseek构建了多层级的语义解析架构,实…...
虚拟主机认证功能
一.认证功能 类型: 1.基于客户端地址的认证 2.基于用户的认证 1.基于客户端地址的认证 nginx是一款模块化软件,功能都是基于模块实现的。 如上图所示,访问认证是使用的这个access_module模块。 这个模块也给我们提供了一些指令…...
BGP协议深度解析:从背景到术语的全面梳理
引言 在复杂的网络架构中,不同自治系统(AS)之间的路由交互至关重要。BGP(Border Gateway Protocol,边界网关协议)作为自治系统间的动态路由协议,承担着跨 AS 路由传递的关键任务。本文将深入探讨…...
初步认识线程
概念 一个线程就是一个 "执行流",每一个线程之间都可以按照顺序执行自己的代码,多个线程之间可以 "同步" 执行多份代码 比如说,原本一个人做的事情,现在交给三个人一起做,那么这三个人就是线程 使用原因 那么为什么要有线程呢?我们直接使用进程不可以…...
【从零开始学习计算机科学】数字逻辑(一)绪论
【从零开始学习计算机科学】数字逻辑(一)绪论 概论信息与数字数字系统中常用的概念数字信号的描述方法概论 从数字(集成)电路的出现到计算机到网络到今天的移动互联网,数字电路是所有现代信息技术的基础。那么数字电路的基础又是什么呢?就是数字逻辑。所有数字系统都是基…...
Tomcat与Jetty的选择
Tomcat与Jetty的对比分析,分核心区别、性能表现及选型建议三部分: 一、核心区别对比 对比维度TomcatJetty架构设计多层级容器结构(Server→Service→Engine等),复杂度高基于Handler链的轻量级设计,扩展性强…...
用AI学编程2——python学习1
一个py文件,学会所有python所有语法和特性,给出注释,给出这样的文件 Python 学习整合文件 """ Python 学习整合文件 包含 Python 的基础语法、数据结构、函数定义、面向对象编程、异常处理、文件操作、高级特性等内容 每个部…...
【教程】宝塔提示请不要将网站根目录设置到以下关键目录中
【教程】宝塔提示请不要将网站根目录设置到以下关键目录中 【教程】宝塔提示请不要将网站根目录设置到以下关键目录中更换目录解决问题 先在宝塔下载一个 【教程】宝塔提示请不要将网站根目录设置到以下关键目录中更换目录解决问题_起尔网【教程】宝塔提示请不要将网站根目录设…...
html常用的文本标签以及属性
HTML标签 HTML通过一系列的标签(也成为元素),来定义文本,图像,链接等等,HTML标签是由尖括号包围的关键字。 标签通常成对出现,包括开始标签和结束标签(也成为双标签)&a…...
城市霓虹灯夜景拍照后期Lr调色教程,手机滤镜PS+Lightroom预设下载!
调色教程 在城市霓虹灯夜景拍摄中,由于现场光线复杂等因素,照片可能无法完全呈现出当时的视觉感受。通过 Lr 调色,可以弥补拍摄时的不足。例如,运用基本调整面板中的曝光、对比度、阴影等工具,可以处理出画面的整体明暗…...
c#面试题整理
1.如何保持数据库的完整性,一致性 最好的方法:数据库约束(check,unique,主键,外键,默认,非空) 其次是:用触发器 最后:才是自己些业务逻辑,这个效率低 2.事…...
数据库基础以及基本建库建表的简单操作
文章目录 一、数据库是啥1.1、数据库的概念1.1、关系型数据库、非关系型数据库1.1、数据库服务器,数据库与表之间的关系 二、为啥要使用数据库2.1:传统数据文件存储2.2:数据库存储数据2.3、结论 三、使用数据库了会咋样四、应该咋用数据库&am…...
基于spring boot使用@Sl4j的日志功能,注解引入后爆红未生效
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 问题描述问题分析解决方案 📃文章…...
《深度剖析架构蒸馏与逻辑蒸馏:探寻知识迁移的差异化路径》
在人工智能模型优化的前沿领域,架构蒸馏与逻辑蒸馏作为知识蒸馏的关键分支,正引领着模型小型化与高效化的变革浪潮。随着深度学习模型规模与复杂度的不断攀升,如何在资源受限的情况下,实现模型性能的最大化,成为了学术…...
使用OpenCV来获取视频的帧率
在OpenCV中,获取视频的帧率(FPS, Frames Per Second)是一个常见的操作,尤其是在处理视频流或进行视频分析时。帧率表示每秒钟视频中的帧数,这个参数对于视频播放速度和时间计算非常重要。 以下是如何使用OpenCV来获取…...
计算机视觉|3D卷积网络VoxelNet:点云检测的革新力量
一、引言 在科技快速发展的背景下,3D 目标检测技术在自动驾驶和机器人领域中具有重要作用。 在自动驾驶领域,车辆需实时、准确感知周围环境中的目标物体,如行人、车辆、交通标志和障碍物等。只有精确检测这些目标的位置、姿态和类别&#x…...
vue-cli3+vue2+elementUI+avue升级到vite+vue3+elementPlus+avue总结
上一个新公司接手了一个vue-cli3vue2vue-router3.0elementUI2.15avue2.6的后台管理项目,因为vue2在2023年底已经不更新维护了,elementUI也只支持到vue2,然后总结了一下vue3的优势,最后批准升级成为了vitevue3vue-router4.5element…...
Jmeter进行http接口测试详解
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 本文主要针对http接口进行测试,使用 jmeter工具实现。 Jmeter工具设计之初是用于做性能测试的,它在实现对各种接口的调用方面已经做的比较…...
大模型AI平台DeepSeek 眼中的SQL2API平台:QuickAPI、dbapi 和 Magic API 介绍与对比
目录 1 QuickAPI 介绍 2 dbapi 介绍 3 Magic API 介绍 4 简单对比 5 总结 统一数据服务平台是一种低代码的方式,实现一般是通过SQL能直接生成数据API,同时能对产生的数据API进行全生命周期的管理,典型的SQL2API的实现模式。 以下是针对…...
靶场之路-VulnHub-DC-6 nmap提权、kali爆破、shell反连
靶场之路-VulnHub-DC-6 一、信息收集 1、扫描靶机ip 2、指纹扫描 这里扫的我有点懵,这里只有两个端口,感觉是要扫扫目录了 nmap -sS -sV 192.168.122.128 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.4p1 Debian 10deb9u6 (protoc…...
nginx服务器实现上传文件功能_使用nginx-upload-module模块
目录 conf文件内容如下html文件内容如下上传文件功能展示 conf文件内容如下 #user nobody; worker_processes 1;error_log /usr/logs/error.log; #error_log /usr/logs/error.log notice; #error_log /usr/logs/error.log info;#pid /usr/logs/nginx.pid;even…...
32.C++二叉树进阶1(二叉搜索树)
⭐上篇文章:31.C多态4(静态多态,动态多态,虚函数表的存储位置)-CSDN博客 ⭐本篇代码:c学习/18.二叉树进阶-二叉搜索树 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) ⭐标⭐是比较重要的部分…...