- 博客(25)
- 收藏
- 关注
原创 线程进阶1
1.对于”悲观乐观“,”重量轻量“,”自旋 挂起等待“是自适应的,初始情况下,synchronized会预测当前锁的锁冲突概率不大,此时以乐观锁模式来运行(此时也是轻量级锁,基于自旋方式实现的),在实际过程中,如果发现锁冲突的情况比较多,synchronized就升级成悲观锁(也就是重量级锁,基于挂起等待实现的)假设我去ATM取钱,我本身账户1000,我想取500,但在取钱的过程中,出现bug了,我按下取钱按钮没反应,我就又按了一下,此时,就产生了两个线程进行扣款操作!
2025-04-30 10:10:35
1049
1
原创 多线程代码案例
在第一个结构中,一旦客户端这把发送的请求多了,每个A收到的请求,都会立即发给B,A抗多少访问量,B就和A完全一样,不同的服务器跑的业务不一样,虽然访问量一样,但是单个访问消耗的硬件资源是不一样的,可能A能承担这些并发量,但是B就不行然后就之间挂了(比如B操作数据库,数据库本身就是分布式系统中相对脆弱的环节)假设一个线程的所有代码都是cpu密集型,这个时候,线程池的数量不应该超过N (设置N就是极限了),设置比N更大,这个时候,也没法提高效率了,cpu已经吃满了,此时更多的线程反而会增加调度的开销。
2025-04-28 08:15:10
1196
1
原创 线程入门4
假设这里是按照1,3,2来执行,当第一个线程(t1)调用此方法执行完1和3时,instance已经非空了,此t1还没执行完,cpu调度器就调度到第二个线程(t2),t2就开始执行,此时t判断instance为非空,就直接return instance了,进一步t2就有可能访问到instance里的属性和方法了,这时就容易出现bug了,这个执行顺序可以是1,2,3 也可以是1,3,2来执(1一定是先执行),不管什么顺序,单线程下都是无所谓的,但是在多线程下,可能就会出问题。结论:保证有序性是禁止指令重排序。
2025-04-27 10:53:52
963
原创 线程入门3
那么对于上面代码这种情况就会产生“死锁”,导致线程卡死,第二个想要加锁成功就需要第一次释放锁,需要执行到程序“1号”位置,但是想要到“1号”位置 就需要 第二次能成功加锁让程序继续往下走,由于第二次加锁处在“阻塞等待“状态,也就执不了代码,最终到不了2号位置,也就无法释放锁,因此线程就直接被卡死了。对于4来说,可以约定加锁的顺序,就可以避免循环等待 (例如针对锁进行编号,加多把锁的时候,先加编号小的锁,再加编号大的锁,所有线程都要遵循这个规则)但C++中std::mutex就是不可重入锁,就会出现死锁。
2025-04-23 20:16:17
698
原创 线程入门2
解决上诉问题的办法是上枷锁,利用关键字synchronized,在使用synchronized的时候,需要搭配一给代码块{},进入{}就会枷锁,{}里的内容执行完毕就会解锁,在已经加锁的状态中,另一个线程也对此同样进行加锁时,就会产生“锁竞争/锁冲突”,后一个线程就会阻塞等待,一直等到前一个线程解锁为止。但如果t线程一直不结束,join默认就会"死等" ,但是一般开发中不建议死等,可以用join(xxx)带参数进行等待,带一个超时时间,超时时间到了t线程还没结束,就会不在等待,继续执行主线程的剩余代码。
2025-04-23 15:00:52
913
原创 线程入门1
谈到并发编程,c++鼓励多使用多进程编程,而java更鼓励引入多个进程 是为了 实现并发编程 => 因为目前是多核cpu时代多进程,实现并发编程,效果也是非常理想但是,多进程编程模型,也有明显缺点。进程太重量,效率不高创建一个进程,销毁一个进程,调度一个进程, 消耗时间都比较多,消耗在资源申请上。为了解决上诉问题,就引入了“线程”(Thread)线程也叫做"轻量级进程",创建,销毁,调度都比线程更快。线程不能独立存在,而是要依附于进程(进程包含线程),进程可以包含一个线程,也可以包含多个线程。
2025-04-21 15:50:11
140
原创 C++入门基础
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。zpp是命名空间的名字,一般开发中是用项目名字做命名空间名。①命名空间中可以定义变量/函数/类型//变量//函数//类型int val;②命名空间可以嵌套//test.cppint a;int b;//N2为嵌套的命名空间int c;int d;③同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。//test.h。
2024-09-19 19:08:45
2125
7
原创 排序算法-归并排序
1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。2. 时间复杂度:O(N*logN)3. 空间复杂度:O(N)4. 稳定性:稳定我的主页还有其他排序算法欢迎大家前往阅读!
2024-09-17 16:59:29
493
原创 排序算法-交换排序
1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序2. 时间复杂度:O(N*logN)如果还想了解更多排序欢迎大家前往我的主页。
2024-09-16 09:59:01
1134
1
原创 排序算法-选择排序
直接选择排序的特性总结1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用2. 时间复杂度:O(N^2)3. 空间复杂度:O(1)4. 稳定性:不稳定堆排序的特性总结1. 堆排序使用堆来选数,效率就高了很多。2. 时间复杂度:O(N*logN)3. 空间复杂度:O(1)4. 稳定性:不稳定。
2024-09-14 14:29:28
927
1
原创 排序算法-插入排序
2.如果要插入的数比前一个数更小则需将前面大的数依次向后移动一次,当遇到的数比插入 的数小时则停下来进行插入。3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定。把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。实际中我们玩扑克牌时,就用了插入排序的思想,从左往右将每一张牌插入到前面排好序的合适的位置。最坏时间复杂度:O(N^2)
2024-09-13 21:24:43
533
3
原创 数据结构-二叉树
在上一篇文章中我们初步认识了一下二叉树,我们主要讲解了一些关于树的概念和堆的结构与实现,详细请看,接下来我们主要讲解普通二叉树的实现。
2024-09-04 14:03:51
1092
6
原创 leetcode-设计循环队列
设计你的循环队列实现。循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。FrontReardeQueue()isEmpty()isFull()// 设置长度为 3// 返回 true// 返回 true// 返回 true。
2024-09-01 20:30:00
1134
2
原创 数据结构-栈和队列
栈(Stack)是一种特殊的线性表,其只允许在表的进行插入和删除操作。栈顶:进行插入数据和删除数据的一端。栈底:相对于栈顶的另一端。原则:栈的数据元素遵循LIFO( Last In First Out )的原则通过图也能明显看出栈的特点只有当栈顶元素出栈后,才能出后面的元素,有点类似于手枪的弹夹,用的时候先一个一个把子弹压进去,最后压进去的子弹最先打出,所以有的进栈也称为压栈。
2024-08-30 17:41:00
1308
4
原创 数据结构-链表
当我们实现了带头双向循环链表的插入和删除数据我们发现,与单链表相比,当前链表无论是在头或者在尾效率都很高,时间复杂度相同为O(N)。这个链表实现也更为简单,所以听起来复杂的链表实现起来并不复杂。
2024-08-30 02:10:53
1462
4
原创 leetcode-随机链表的复制
给你一个长度为n的链表,每个节点包含一个额外增加的随机指针random,该指针可以指向链表中的任何节点或空节点。构造这个链表的。深拷贝应该正好由n个节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的next指针和random指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。。例如,如果原链表中有X和Y两个节点,其中。那么在复制链表中对应的两个节点x和y,同样有。返回复制链表的头节点。用一个由n个节点组成的链表来表示输入/输出中的链表。
2024-08-27 19:18:42
737
3
原创 字符函数和字符串函数
2. 字符转换函数在编程的过程中,我们经常要处理字符和字符串,为了⽅便操作字符和字符串,C语言标准库中提供了⼀系列库函数,接下来我们就学习⼀下这些函数。
2024-08-26 11:22:28
790
4
原创 深入理解指针(上)
在C语言的学习中,对于我们初学者来说第一次接触到指针大部分都会觉得会比C语言的其他基础语法要难许多,指针本身其实挺好理解,但在实际代码中总会让人感到难度,下面我将从基础到深入全面为你讲解指针,希望通过本篇文章会让你对指针理解的更加通透。
2024-08-21 00:55:52
1266
7
原创 C语言分支和循环语句
1.分支结构C语⾔是结构化的程序设计语⾔,这⾥的结构指的是顺序结构、选择结构、循环结构,C语⾔是能够实现这三种结构的,其实我们如果仔细分析,我们⽇常所⻅的事情都可以拆分为这三种结构或者这三种 结构的组合。我们可以使⽤if实现分⽀结构,使⽤forwhile实现循环结构。1.分支结构1.1 if语句if 语句的语法形式如下:if ( 表达式 )语句表达式成⽴(为真),则语句执⾏,表达式不成⽴(为假),则语句不执⾏。在C语⾔中,为假。
2024-08-09 11:33:00
1483
2
原创 初识C语言
C语言是一门编译型计算机语言,C语言源代码都是文本文件,C语言代码是放在.c为后缀的文件中,文本文件本身是无法执行的,必须通过编译器的翻译和链接器的链接,生成二进制的可执行的文件,可执行文件才能执行。因此想要写出来的代码计算机能看懂就需要把代码翻译成机器语言,就会生成所对应打目标文件(.obj为后缀的文件),我们把翻译它的程序叫做编译器,除了把代码能翻译成计算机能看的懂的语言,还需要将另外一些库文件和目标文件打包放在一起最后才能生成可执行文件(.exe文件)。1.C语言的发展史和学习C语言的重要性。
2024-05-30 12:51:51
333
4
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人