JavaEE 多线程详细讲解(1)
1.线程是什么
(shift + F6)改类名
1.1.并发编程是什么
(1)当前的CPU,都是多核心CPU
(2)需要一些特定的编程技巧,把要完成的仍无,拆解成多个部分,并且分别让他们在不同的cpu上运行。
要不然就会编程,一核有难,多核围观的场景
并发编程指的是(并行+并发)
(3)通过多进程编程的模式就可以达到并发编程的效果。
因为进程可以被调度到不同的cpu上面运行
此时就可以把多个cpu核心核心都很好的利用起来
(4)虽然多进程编程可以解决上述问题,但是带来了新的问题。
1.2.问题?
(1)在编程过程中,服务器开发的圈子李,这种并发编程要能够给多个客户端提供服务。
如果同一时间来了很多客户端,服务器如果只利用一个cpu核心工作,速度会比较慢
(2)多搞几个厨师,来炒菜,这样就大幅的提高了效率
(3)一个比较好的做法就是每个客户端连上服务器,服务器都创建一个新的进程,给客户端提供服务,这个客户端断开了,服务器再把进程示范掉
如果服务器,频繁有客户端来来去去,服务器就需要频繁创建销毁进程。(服务器响应速度会变慢)
1.3.如何解决这个问题?线程的引出
引入线程,主要的出现,就是为了解决上述进程,太重量的问题
(1)线程(thread)也叫做轻量级进程(创建销毁的开销更小)。
(2)线程可以理解为进程的一部分,一个进程中可以包含一个线程或者多个线程
(3)描述进程使用的是PCB这样的结构体,事实上更严格的说,一个PCB其实是描述一个进程的,若干个PCB联合在一起,是描述一个进程的。
(4)pcb中包括(pid 内存指针 文件描述表 状态上下文,优先级,记账信息 tgid)每一个线程所提供的pid是不一样的但是tgit是一样的,所以我们可以用tgit来判断这个线程是不是在一个线程下面
(5)还要同一个进程的若干个线程,这里的内存指针和文件描述表,其实是同一个。
(6)状态上下文优先级记账信息每个线程有一组自己的属性
(7)同一个进程中的若干个线程之间,是相同的内存资源和文件资源的。
线程之间可以互相访问
进程是系统资源分配的基本单位
线程是系统调度执行的基本单位
同一个进程包括N个线程,线程之间是共用资源
只有你创建第一个线程的时候,去进行资源的申请操作,后序再创建线程,都没有申请资源的过程了。
1.3.1并发编程
(1)在我们引入了进程以后,那么我们就可以思考,进程的作用是什么?
(2)图解举例
(3)我们现在的计算机不都是好多核心,所以我们可以用多个线程来对工作进行拆分
(4)由于成本很高,而且电脑的核心也并不是特别的多,所以我们引出了多线程编程。
相当于线程为进程分担了问题
(5)这时候就有同学提出问题,是不是线程越多越好,这当然不是,因为线程的调度也是需要分配资源的,合适的线程可以帮助你来更好的管理资源,但是如果线程过多的化那么线程就会变慢。
(6)其中我们还要思考一个问题就是线程的调度资源到底花费到哪里
(7)其中多核CPU才能进行这种操作
(8)其中,在线程不是太多的情况下,也可能发生线程安全的问题。
1.4总结
总结:为啥说线程更加轻量,开销更小,核心就在于,创建进程可能包含多个线程,这个过程中,涉及到资源分配,资源释放。
1.5线程于进程的关系以及相关问题
1.6关键面试题(线程和进程的区
别)
2.代码实现线程和进程、
线程本身是操作系统提供的。
操作系统提供了API让我们操作系统
JVM就对操作系统的api进行封装
线程这里提供了thread类实现了封装
2.1线程的代码实现
其中,操作系统提供了api来对线程进行操作,然而我们的编译器,使用了JVM(java虚拟机)来进行操作,操作系统的api,其中,在java中我们使用的就是Thread类来对线程进行操作
2.1.1Thread 代码的基本实现
其中,run方法是Thread中本来就有的方法 ,我们把他重写了
进入源代码
可以看到我们重写了run方法。
2.1.1.1注意事项
(1)上面的这段代码其实是创建了两个线程,分别是main线程,另一个就是t线程
(2)其中main是主线程,也就是jvm在运行的时候就会创建出来。
(3)其中一个线程中至少包含一个进程,然后再进程中,至少包含一个线程,在没有引入多并发编程之前,我们运行的程序都是一个进程,然后我们在一个线程下面编写代码。
(4)在上面的程序中就是,一个进程,然后进程的下面有两个线程,分别是t线程,然后是jvm生成的主线程mian
2.1.2线程的状况(线程一直进行来进行分析)
其中try catch来对其进行捕获,是因为防止在其他线程或者什么东东调用正在休眠的线程,这时候就会一直等下去,也就是阻塞,所以我们要用trycatch来进行处理
try {// 尝试执行这里的代码,可能会抛出异常
} catch (ExceptionType1 e) {// 如果try块中的代码抛出了ExceptionType1类型的异常,则执行这里的代码
} catch (ExceptionType2 e) {// 如果try块中的代码抛出了ExceptionType2类型的异常,则执行这里的代码
} finally {// 无论是否发生异常,finally块中的代码总是会被执行
}
代码整体实现
package thread;
class MyThread extends Thread{public void run(){while(true){System.out.println("HelloThread1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
public class Demo1 {public static void main(String[] args) {Thread t = new MyThread();t.start();while(true){System.out.println("HelloThread1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
其中main和t线程是并发执行的
其中我们要注意的一点就是sleep后面的休眠时间的单位是ms,其中sleep的作用就是将这个停一下在方到系统上面的CPU上面进行执行
时间到了以后就会解除阻塞状态也就是。
它可以让我们的CPU的调度有休息可以更好的处理资源的调度
2.1.3线程的使用情况(2.1.2中的代码)
在运行的时候我们可以看到每秒钟打印一次
其中main可能t线程的前面
t线程也可能在main线程的后面
也就是谁抢上资源谁就进行输出
2.1.4其他一些关系线程的东西就一起来说明了
(1)
总的来说就是,我们定义了一个线程的基本框架(MyThread类),其中在main方法中的Thread t = new MyThread只是实例化这个对象而已,也没有创建线程,这时候的start是Thread中里面的方法,只有在调用这个方法的时候,才会使用我们实例化的线程框架,来创建线程
通俗点说就是
(2)其中要注意的是
所以刚才写的代码就是线程的串行执行
2.2Thread的五种写法
2.2.1第一种创建一个类继承Thread方法
这个是我们一开始说的那个方法
2.2.2第二种创建一个类描述线程,实现Thread的方法
这个方法实现线程的方式是比较好的方式
它能大大的降低耦合度
我们不同于第一种创建,我们是实例化Thread然后把MyRunnable作为参数传入实例化的对象中作为参数
两种Thread的对比(1)和(2)种方法
2.2.3第三种创建 使用匿名内部类创建线程框架(继承Thread类)
代码实现
这个定义了一个匿名内部类来对,这个匿名内部类直接继承Thread类然后重写Thread的中的run方法,然后最后t.star就可以了
总结
2.2.4第四种创建方式lambod表达式创建(JDK8的新属性)
这个方式可以理解为用函数式接口的方法
在Thread类中式没有抽象方法的,但是在Thread中实现了Runnable接口,里面有一个run抽象方法,lambod表达式就会重写这个方法来做出线程的框架
相较于Thread的内部类来实现来说 lambad表达式只能用函数式接口来重写run,但是比内部类实现来说方便许多,匿名内部类实现的化比它麻烦一点,但是它的扩展性比lamda表达式要好很多
注意的一点就是主线程一直在其他线程完成以后再执行的
代码实现
2.2.5第五种方法是实现Runnable重写run使用内部类
总结
2.3线程的几种其他用法
2.3.1给线程定义名字
(1)在线程的结尾来定义名字
代码示例
package thread;public class Demo6{public static void main(String[] args) {Thread t = new Thread(()->{while (true){System.out.println("make name from Thread");try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}},"Frank");t.start();}
}
2.4Catch中写的是什么?Sleep的注意事项
(1)
(2)
其中我们要注意的就是在main方法中我们有两种方法来处理sleep
分别时 :try catch 和Throws
用try catch 可以捕获异常然后程序员选则如何处理这个异常
用Throws是捕获的异常必须要优先处理
2.5小结
3线程的区别
线程分为分为前台线程和后台线程
前台线程就是这个线程不结束java程序
后台线程就是这前台线程结束那么他就结束了
4将进程设置为后台进程
代码实现
public class DaemonThreadExample {public static void main(String[] args) {// 创建一个线程Thread daemonThread = new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {System.out.println("Daemon Thread is running...");Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}});// 将线程设置为后台线程daemonThread.setDaemon(true);// 启动线程daemonThread.start();// 主线程执行完毕,由于daemonThread是后台线程,程序不会等待它执行完毕就会退出System.out.println("Main thread is exiting...");}
}
5.其他知识的扩充
(1)
6.如何让线程中断
我们可以定义一个布尔值的变量其中,我们可以用布尔值来控制循环的开始和结束。
代码实现
其中要注意的是外部类成员是不会报错
(2)线程的中断
总结一下,`t`线程在`sleep`状态时,就像你的朋友决定去睡觉并且不想被打扰一样,它是不会响应中断请求的。如果你想让它在需要的时候提前醒来,你需要在编写代码时,让它能够检查并响应中断请求。
6.1线程如何更好的中断
代码解析
首先,我们要明白什么是线程中断。在Java中,线程中断是一种协作机制,允许一个线程请求另一个线程停止它正在做的事情。这通常是因为某种原因,比如用户取消了操作,或者系统需要释放资源。
Thread.currentThread().isInterrupted()
这个方法用来检查当前线程是否已经被其他线程中断。中断状态是一个标志,当一个线程调用另一个线程的
interrupt()
方法时,它会设置这个标志。
while (!Thread.currentThread().isInterrupted())
这个循环的意思是:“只要当前线程还没有被中断,就继续执行循环里的代码。” 如果线程在循环内部被中断(比如其他线程调用了它的
interrupt()
方法),那么
isInterrupted()
方法会返回
true
,循环条件变为
false
,循环就会停止。
现在,让我们看一个简单的例子:
假设你正在煮一壶水,并且你想在水开之前不断检查它。你可以把煮水的过程想象成一个线程的任务。如果突然有急事要离开,你可能会想中断这个线程(也就是停止检查水是否开了)。
在这个例子中,
while (!Thread.currentThread().isInterrupted())
就像是你在不断地问自己:“我是不是应该停止检查水是否开了?” 只要你没有被中断(也就是没有急事发生),你就会继续检查。一旦你收到中断信号(比如有人叫你),你就会停止检查并去处理其他事情。
Thread.interrupt()
方法就像是有人按下了停止按钮,告诉线程:“你应该停止你正在做的事情了。” 而
isInterrupted()
方法就像是线程在回答:“好的,我已经收到停止的信号了。”
这时候当我们进行运行的时候会发现虽然我们返回了true想要中断,但是却没有中断,这是因为sleep会将false再修改回true,这是为了能够让程序员更好的控制线程而不是让程序自己控制线程,我们可以再catch中选择他是继续往下进行还是结束
图解
7线程的其他方法
详细图解
其要注意的就是前台线程结束后台线程不管如何都会结束,而后台线程结束那么前台线程是不会结束的。
注意事项
3.Thread中的join方法(线程的阻塞)
3.1join方法的本质
(1)
图解
(2)join方法的本质是指的是使用了这个方法的线程就会阻塞
图解
所以main线程永远是最后进行执行的。
其中要注意的就是如果没有设置sleep就是哪个线程先用join那么哪个线程就先执行,还有就是只有start了以后才能join,如果休眠时间一样也按这种方式处理,如果休眠时间不一样,那么休眠间短的线程先执行然后再是休眠时间最长的,最后再是main线程。
3.2代码示例
public class JoinExample {public static void main(String[] args) {Thread thread1 = new Thread(() -> {System.out.println("Thread 1 starting...");try {Thread.sleep(1000); // 模拟耗时操作} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread 1 ending...");});Thread thread2 = new Thread(() -> {System.out.println("Thread 2 starting...");try {Thread.sleep(1500); // 模拟耗时操作,比线程1稍微长一些} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread 2 ending...");});thread1.start(); // 启动线程1thread2.start(); // 启动线程2try {thread1.join(); // 等待线程1完成thread2.join(); // 等待线程2完成} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Main thread continuing..."); // 当两个子线程都完成后,主线程继续执行}
}
3.3join最大等待时间
1. 概念 join方法可以理解为谁调用这个方法谁就会被阻塞然后等待这个线程运行结束以后然后恢复执行。
2.这个就相当于join等待不能一直等待,我们可以规定一个时间来限制他。
图示(深度解析)
3.4sleep 和join 方法的区别
(1)sleep在java的库中是native方法也就是本地方法,它的底层我们是看不到的
(2)通俗点来讲,sleep是控制这个线程的休眠时间而不是两个代码的执行的间隔时间。
(3)sleep是根据时间戳来对其进行休眠时间的判定
(3)system.currentTimeMillis()这个代码可以获得我们系统的时间戳
注意事项
(4)对于join方法来说,这个就是真正的阻塞,只有前面没有调用这个方法的线程执行结束,这个阻塞才会恢复然后执行这个调用这个join方法的线程
4.引出线程安全问题(为下一篇文章做基础)
4.1引言
(1)我们之前提到过线程的状态,其中我们也可以叫它为PCB状态,其中linux 和windos系统,linux系统有非常成熟的系统来操控PCB,当然windos系统中也会有选项来对其进行操作,只不过性能方面没有比linux更好罢了。
(2)其中在我们java的jdk中的jvm虚拟机中,nb的大佬程序员都为我们封装好了这些东西来对其进行操作,相较于C++来说,java方便太多,C++语言的特征是性能高稳定但是编写难度较高。
4.2 六种PCB状态梳理
(1)NEW状态
这个状态就是Thread线程的对象已经有了,没有进行start,系统内部的线程还没有创建。
(2).Terminated状态
这个状态是Thread线程的对象有了,也执行完毕,然后被销毁,最后还剩下一个Thread对象。
(3)Runnable状态(就绪状态)
这个指的是,这个线程已经调度到了系统的CPU上面,其中有两种情况。
第一种就是:这个线程已经在CPU上面,但是还没有执行
第二种就是:这个线程已经在CPU上面进行执行了
!!!!!!我看了很多资料讲解的都不是很好,他们将这两种状态分开了,叫出了两种名称,我认为其实没啥用,因为都已经到CPU上面了,已经不是人能决定的了,而是全部由系统决定,你就算再nb你能对系统进行操作吗??所以这两种状态我都称之为就绪状态。
5.阻塞的三种状态讲解
最后一个状态我们在下一篇文章中进行讲解
打开idea的文件夹找到查看线程状态的软件,来对阻塞进行讲解
可以看到,join是死等,join带有最大阻塞时间和sleep休眠是TIMD-WAITING是带有时间的阻塞。
这个的作用就是在你以后工作的时候来判断你的各个线程的状态来更好的开发项目
(1)线程不安全示例
相当于它会重复的对数据进行读取这是非常不好的。
我们可以进行串行执行
这样就好了
所以死锁问题就是这样产生的。
(1)为什么,发生这种问题的简单原因。
(2)其中在上面的加到5000的情况下面还有一个情况就是两个加在一起小于5w的情况。
在多线程环境中,每个线程都有自己的 CPU 缓存和工作内存。当一个线程修改了变量的值时,这个变化不会立即反映到主内存中,而是在适当的时机才会同步到主内存中。其他线程在读取这个变量的值时,可能会直接从自己的 CPU 缓存或者工作内存中读取,而不是从主内存中读取,这就导致了可能读取到旧值的情况发生。
相关文章:
JavaEE 多线程详细讲解(1)
1.线程是什么 (shift F6)改类名 1.1.并发编程是什么 (1)当前的CPU,都是多核心CPU (2)需要一些特定的编程技巧,把要完成的仍无,拆解成多个部分,并且分别让…...
数据分析从入门到精通 1.numpy剑客修炼
会在某一瞬间突然明白,有些牢笼是自己给自己的 —— 24.5.5 一、数据分析秘笈介绍 1.什么是数据分析 是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律。使得数据的价值最大化 案例: 分析用户的消…...
【iOS】KVO
文章目录 前言一、KVO使用1.基本使用2.context使用3.移除KVO通知的必要性4.KVO观察可变数组 二、代码调试探索1.KVO对属性观察2.中间类3.中间类的方法3.dealloc中移除观察者后,isa指向是谁,以及中间类是否会销毁?总结 三、KVO本质GNUStep窥探…...
python json字符串怎么用format方法填充参数值报KeyError
python json字符串怎么用format方法填充参数值报KeyError 需求问题分析解决方案 需求 因为python中的字典和json中的一些变量有差异,比如:json中有null、true,在python中就不会被识别,只能转换成字符串,在通过loads()…...
C++新手村指南:入门基础
目录 C概念 C发展史 C关键字(C98) 命名空间 命名空间的定义 命名空间的使用 C中的输入&&输出 缺省参数 缺省参数的概念 缺省参数的分类 函数重载 函数重载概念 函数重载实现 引用 引用的概念 引用的特性 常引用 引用的使用场景…...
智慧旅游推动旅游服务智慧化转型:借助智能科技的力量,实现旅游资源的精准匹配和高效利用,为游客提供更加便捷、舒适的旅游环境
目录 一、引言 二、智慧旅游的定义与特点 (一)智慧旅游的定义 (二)智慧旅游的特点 三、智能科技在旅游服务中的应用 (一)大数据分析助力旅游决策 (二)人工智能实现个性化推荐…...
Hikyuu-PF-银行股轮动交易策略实现
今天,带来的是“如何使用 Hikyuu 中的投资组合来实现银行股轮动交易策略”。 这个策略的逻辑很简单:持续持有两支市净率最低银行股,然后每月换仓 定义回测周期与回测标的 同样,首先定义回测周期: # 定义回测日期 …...
【氮化镓】GaN功率器件在转换器设计中的挑战
I. 引言(INTRODUCTION) 宽带隙(WBG)器件的重要性: 引言部分首先强调了宽带隙(WBG)器件在高频、高效率电力电子技术中的关键作用。这些器件,包括碳化硅(SiC)和氮化镓(GaN),相较于传统的硅功率器件,具有显著的优势。宽带隙半导体材料的高击穿场强允许设计更薄的漂…...
DOTA-Gly-Asp-Tyr-Met-Gly-Trp-Met-Asp-Phe-NH2,1306310-00-8,是一种重要的多肽化合物
一、试剂信息 名称:DOTA-Gly-Asp-Tyr-Met-Gly-Trp-Met-Asp-Phe-NH2CAS号:1306310-00-8结构式: 二、试剂内容 DOTA-Gly-Asp-Tyr-Met-Gly-Trp-Met-Asp-Phe-NH2是一种重要的多肽化合物,其CAS号为1306310-00-8。该多肽包含一个DO…...
CopyClip for Mac - 高效复制粘贴,轻松管理剪贴板
CopyClip for Mac,一款专为Mac用户打造的剪贴板管理工具,让你在复制粘贴的日常任务中,享受到前所未有的高效与便捷。 它常驻在菜单栏中,时刻准备为你服务。一旦你复制了内容,CopyClip就会自动将其保存至历史记录中&…...
[windows系统安装/重装系统][step-1]U盘启动盘制作,微软官方纯净系统镜像下载
前言 U盘至少8GB吧我这刚好有个空闲的U盘8GB容量,制作启动盘且放入一个最新win10官方镜像足够 不是天天装系统,至少USB2.0 (我用的2.0的一个闲置U盘)即可,当然平时传资料什么的3.0会快些 U盘启动盘仅需要制作一次, U盘启动盘制…...
AI换脸原理(4)——人脸对齐(关键点检测)参考文献2DFAN:代码解析
注意,本文属于人脸关键点检测步骤的论文,虽然也在人脸对齐的范畴下。 1、介绍 在本文中,重点介绍了以下几项创新性的成果,旨在为人脸关键点检测领域带来新的突破。 首先,成功构建了一个卓越的2D人脸关键点检测基线模型。这一模型不仅集成了目前最优的关键点检测网络结构,…...
Sarcasm detection论文解析 |使用 BERT 进行中间任务迁移学习的刺检测
论文地址 论文地址:https://www.mdpi.com/2227-7390/10/5/844#/ github:edosavini/TransferBertSarcasm (github.com) 论文首页 笔记框架 使用 BERT 进行中间任务迁移学习的讽刺检测 📅出版年份:2022 📖出版期刊:Mathematics &…...
docker系列9:容器卷挂载(下)
传送门 docker系列1:docker安装 docker系列2:阿里云镜像加速器 docker系列3:docker镜像基本命令 docker系列4:docker容器基本命令 docker系列5:docker安装nginx docker系列6:docker安装redis docker系…...
QT ERROR: Unknown module(s) in QT: xlsx怎么办
现象描述 QT编译c代码的时候,报这种QT ERROR: Unknown module(s) in QT: xlsx,应该如何解决? 这里,我简单记录一下自己的解决问题过程。有可能,对遇到同样的问题的你,也有所帮助 第一步 检查perl是否安装…...
npm install 卡在reify:rxjs: timing reifyNode的解决办法
今天要逆向跑一个electron,但是npm install一直卡在 reify:element-plus: timing reifyNode:node_modules/lodash Completed in 6664ms这里一动不动,一番研究之后发现可能跟用的镜像有关系,我原本是官方镜像,总感觉第三方镜像有一…...
VScode 无法连接云服务器
试了很多方法,比如更换VScode版本,卸载重装,删除配置文件 重启电脑,都无法成功。最后重置电脑后才连接上,但是重启服务器后又出现该问题。 方法一:修改环境 方法二:把vscode卸载干净重下...
Kafka 面试题(二)
1. 简述Kafka 的工作流程 ? Kafka的工作流程涉及多个关键组件和步骤,确保了消息的可靠传输和处理。以下是Kafka工作流程的简要概述: 生产者发布消息:生产者(Producer)是Kafka工作流程的起点,它…...
Spring Cloud Kubernetes 本地开发环境调试
一、Spring Cloud Kubernetes 本地开发环境调试 上面文章使用 Spring Cloud Kubernetes 在 k8s 环境中实现了服务注册发现、服务动态配置,但是需要放在 k8s 环境中才能正常使用,在本地开发环境中可能没有 k8s 环境,如何本地开发调试呢&#…...
基于二维CS-SCHT变换和扩频方法的彩色图像水印嵌入和提取算法matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................................................. % figure; % subplot(121);…...
设计模式——行为型模式——策略模式(含实际业务使用示例、可拷贝直接运行)
目录 策略模式 定义 组成和UML图 代码示例 实际业务场景下策略模式的使用 策略模式优缺点 使用场景 JDK中使用策略模式示例 参考文档 策略模式 定义 策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化…...
Rust:foo(x)、foo(x),还是foo(x.clone())?
一、一个实际问题 用一个线性代数库的求逆矩阵函数时,让我很不爽,我必须按照下面的形式写调用代码: ...if let Some(inv_mat) try_inverse(mat.clone()) {...}...注意 try_inverse 函数的参数传递形式,函数参数是 mat.clone() 而…...
「JavaEE」多线程案例1:单例模式阻塞队列
🎇个人主页:Ice_Sugar_7 🎇所属专栏:JavaEE 🎇欢迎点赞收藏加关注哦! 多线程案例分析 🍉单例模式🍌饿汉模式🍌懒汉模式🍌指令重排序 🍉阻塞队列&a…...
pdf2htmlEX:pdf 转 html,医学指南精细化处理第一步
pdf2htmlEX:pdf 转 html,医学指南精细化处理第一步 单文件转换多文件转换 代码:https://github.com/coolwanglu/pdf2htmlEX 拉取pdf2htmlEX 的 Docker: docker pull bwits/pdf2htmlex # 拉取 bwits/pdf2htmlex不用进入容器&…...
【webrtc】MessageHandler 6: 基于线程的消息处理:StunRequest实现包发送和超时重传
G:\CDN\rtcCli\m98\src\p2p\base\stun_request.cc使用OnMessage 实现包的发送和包的超时重传StunRequest 一个StunRequest 代表是一个独立的请求的发送STUN消息 要不是发送前构造好的,要不就是按照需要构建的使用StunRequestManager: 每一个STUNRequest 携带一个交互id 写入m…...
《Python编程从入门到实践》day22
# 昨日知识点回顾 方法重构、驾驶飞船左右移动、全屏显示 飞船不移动解决,问题出在移动变量x更新 # Ship.pysnipdef update(self):"""根据移动标志调整飞船的位置"""# 更新飞船而不是rect对象的x值# 如果飞船右移的标志和飞船外接…...
介绍 ffmpeg.dll 文件以及ffmpeg.dll丢失怎么办的五种修复方法
ffmpeg.dll 是一个动态链接库文件,属于 FFmpeg运行库。它在计算机上扮演着非常重要的角色,因为它提供了许多应用程序和操作系统所需的功能和组件。当 ffmpeg.dll 文件丢失或损坏时,可能会导致程序无法正常运行,甚至系统崩溃。下面…...
AI换脸原理(6)——人脸分割介绍
一、介绍 人脸分割是计算机视觉和图像处理领域的一项重要任务,它主要涉及到将图像中的人脸区域从背景或其他非人脸区域中分离出来。这一技术具有广泛的应用场景,如人脸识别、图像编辑、虚拟背景替换等。 在计算机视觉(CV)领域,经典的分割技术可以主要划分为三类:语义分…...
【C++并发编程】(二)线程的创建、分离和连接
文章目录 (二)线程的创建、分离和链接创建线程:示例线程的分离(detach)和连接(join) (二)线程的创建、分离和链接 创建线程:示例 线程(Thread&a…...
利用生成式AI重新构想ITSM的未来
对注入 AI 的生成式 ITSM 的需求,在 2023 年 Gartner AI 炒作周期中,生成式 AI 达到预期值达到顶峰后,三分之二的企业已经将生成式 AI 集成到其流程中。 你问为什么这种追求?在预定义算法的驱动下,IT 服务交付和管理中…...
白城学做网站/深圳网络优化推广公司
C语言与OO思想介绍 C的特点与OO思想 C语言有一个优点,即它的速度可以很快。写出来的程序可以很精练、简单、小巧,不用为了解决某个问题环绕太平洋一大圈。 但如果将C和C相比较,C就经常会为了解决某个问题绕一个大圈,所以代码量相对…...
巴彦淖尔市 网站建设/百度宁波运营中心
2017跟着小虎玩着去软考--项目管理师系列 趣味好玩解析2015年下半年信息系统项目管理师上午试题21-25题【小虎梦想】小虎有一个梦想,希望像专业的计算机考试,如全国计算机软件技术与软件专业资格(水平)考试(简称软考&a…...
广水做网站/中国2022年重大新闻
要带本科毕设嘛,所以对这个要多少了解一下,然后就搜索了一下,之前搜索过一次,没发现什么啊,这次一搜索发现不错的东西,特此记录,主要是转载。以下内容转载自CVPR 2019轨迹预测竞赛冠军方法总结赛…...
canvas做的网站/seo关键词排名工具
引言 只要设计到数据,就会涉及到数据的排序问题,比如给你随机给你五个整数 3,1,5,2,4 。让你从小到大进行排序,那我们该怎样才是实现对这些整数的排序呢 ? 答案是多种多样的&#x…...
做淘宝图的素材搜索网站/百度投诉中心24小时电话
就只是贴了一个代码,部分解释写在代码注释里面了,之后会补上文字解释: 1. 第一种方式: import torch import torchvision import time #用于计时的 from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten,…...
建站之星模板制作/自媒体平台注册
在命令模式下,输入:.,$d 一回车就全没了。 表示从当前行到末行全部删除掉。 用gg表示移动到首行。...