- 博客(19)
- 收藏
- 关注
原创 多线程---锁策略、CAS、锁的优化
ABA问题:假设有两个线程t1 和 t2,有一个变量 num 值为A,当线程t1使用CAS对num进行修改的时候会判定sum里的值是否为A当为A的时候才会进行交换,但是有可能当 t1 在执行的时候,t2把num的值从。当2个线程都是写锁或者1个线程是读锁1个线程是写锁的时候,线程之间互斥,由于互斥会引起线程等待,所以减少互斥就能提高程序效率,当要修改数值的时候,会先比较 V 与 A 的值,当 V 与 A 的值相等的时候(说明没有别的线程修改过数据)才会让V 与 B 交换 (相当于赋值),否则不做任何操作。
2024-08-27 19:41:12
605
原创 线程池——Java
和进程相比线程的创建和消费的开销的确很小,但是随着业务的发展,线程使用的频次越来越多,创建和销毁线程的开销也越来越大,使用线程池就能改善线程频繁的创建和开销。线程池就是系统提前申请好一些线程放在一个地方,当我们要使用多线程的时候直接拿出来使用,用完之后再还回到这个地方,这个就避免了线程的频繁创建与开销,这样就能提高整体的效率。,当一个线程池空闲下来的时候,非核心线程不会立刻被销毁,会根据keepAliveTime 设置的时间来销毁线程。,工厂是指一种工厂设计模式,是一种常见的设计模式。
2024-08-23 15:52:48
706
原创 死锁的相关情况
这位5位哲学家同时拿起左手边的筷子,这时每位哲学家都拿到一把筷子,但是没有吃饱不会放下手中的筷子,这就导致这5位哲学家在互相等待对方的筷子但不会放下自己手中的筷子,这就陷入无限等待的状态。线程t1要继续对锁2加锁,可是锁2这时被线程t2加上锁,线程t1只能阻塞等待线程t2释放锁,但是,线程t2要释放锁就要对锁1加上锁,也要阻塞等待线程t1释放锁。两个线程,两把锁,线程t1先对锁1加锁,线程t2对锁2加锁,线程t1不释放锁1的情况下对锁2加锁,线程t2不释放锁2的情况下对锁1加锁。
2024-08-12 12:03:33
301
原创 线程安全问题的原因和解决方案
就存在t1线程刚执行完相加指令还没把结果保存到内存中,t2线程就把加好的数据存在内存中,当t1线程把数据保存到内存中之后,就把t2线程已经加完的数据给覆盖掉了,就导致t2线程执行了count++,但是count++的结果没有保存下来。,那上述代码中的count++就不是原子的,count++在CPU上可以简单分为有3条指令(1.load(从内存上加载数据) 2.add(执行相加操作) 3.save(把结果保存到内存中) ),由于线程调度的随机性,,这就是线程安全问题,程序运行结果与我们的预期不符。
2024-08-11 22:21:31
814
原创 Java 线程的几种状态
在多线程中由于存在线程安全问题,在使用多线程的时候往往会使用锁来避免多线程的安全问题,当同时给多个线程加上同一个锁的时候,这几个线程就会进行锁竞争,当这些线程中有一个线程拿到锁之后,剩下的线程就会进入由锁竞争引起的阻塞状态,此时的状态就是BLOCKED状态。上述代码中创建了两个线程一个t1,一个t2,在t1线程的run方法中通过执行死循环让t1线程一直运行,而t2线程通过t1.join(2000)方法来等待线程t1 2s,2s后t2线程就结束等待,所以t2线程的状态就是TIMED_WAITING。
2024-08-10 12:44:48
674
原创 Thread 类的基本用法
从上述代码可以看出,t1线程中的for循环运行5次休息5秒,而t2线程的for循环运行2次,休息2买秒 ,t1和t2线程并发执行后按理来说应该是t2线程先结束,,当线程t1执行时,由于isTrue 为true,在t1线程中的run方法一直在循环,当2s后t2线程执行到isTrue = false,就说明t2线程只会等待t1线程2s,如果t1线程2s后没有执行结束,那t2线程就执行结束,不再等待t1线程。,这样如果t2先线程执行完了就不会结束线程,而是会等待t1线程结束后,t2线程才结束。
2024-08-09 10:37:04
642
原创 进程和线程的区别和联系
5.在同一个进程中的多个线程之间。2.线程创建和销毁的开销比进程。每个线程之间都可以按照顺序执行自己的代码。线程,每个进程中至少有一个线程(主线程)(创建,销毁,调度的行为线程比进程。区别与联系:1.线程比进程更加。的基本单位,线程是系统。
2024-08-06 23:17:31
201
原创 进程的调度
在单核系统中,由于一个核心只能运行一个进程,当我们运行多个进程后,CPU有会根据进程的状态,进程的优先级等先运行一个进程1,一段时间后再运行另一个进程2,再一会后再去运行其他进程3,由于CUP的这种工作情况,就需要记录进程的上下文,当再次运行进程1时,才知道刚刚运行到哪里,进程的运行才能持续。简单来说就是这个时刻CPU运行进程1,过一会执行进程2,再过一会运行进程3,由于CPU的运算速度很快,在进程间的切换也很快,所以在我们看来这些进程都是'同时执行'的,这就叫做。进程的优先级是可以自行调节的。
2024-07-29 22:56:37
363
原创 封装、继承和多态
这时我们就可以定义一个动物类,这个类包含了这些重复的成员变量和成员方法,这时狗这个类就可以继承动物这个类,那些重复的成员变量和成员方法在狗这个类中就不用再出现,但是狗这个类也是包含这些重复的成员变量和成员方法,因为狗继承了动物这个类。在上述的代码中,在Son类中并没有调用Dad类的方法,那为什么在调用子类的构造方法时会调用父类的构造方法?,这样产生新的类,称派生类。此时当在父类写一个和子类方法名一样的show()方法时,d对象调用的show()方法是父类的还是子类的?
2024-03-22 13:54:32
2888
3
原创 初步认识Java中的类和对象
假设我们要洗衣服,面向过程的思想像是现代的洗衣方式,这里共有:人,洗衣机,洗衣粉,衣服这四个对象,人把衣服放进洗衣机,加入洗衣粉,启动洗衣机,洗衣机洗衣服。在Java中定义了一个类之后,这个类就相当与一种新的类型,和int,double类型类似,只不过这两种是Java的内置类型,而我们定义的类是自定义类型。属性主要是用来描述类的,称之为类的成员属性或者类成员变量。再比如把洗衣机看做一个类别,它的属性就可以有:产品品牌,型号,产品重量,外观尺寸,颜色等它的功能就可以有:洗衣,烘干、定时等。
2024-03-18 20:44:59
484
2
原创 Java中8中基本的数据类型
Short,int的包装类型为Integer,long的包装类型为Long,float。// s和i都是整形,s范围小,i范围大,当将s赋值给i时,编译器。// int的范围比short范围大,会有数据丢失,不安全,需要。Float,double的包装类型为Double,char。Java中有8中基本的数据类型,分别是。中,当参与运算数据类型不一致时,就会进行类型转换。的包装类型为Character,boolean。其中字节的包装类型为。Byte ,short的包装类型为。型,浮点型默认为double。
2024-03-12 11:52:54
286
1
原创 C语言的编译和链接
顾名思义翻译环境就是把所有的源文件(test.c)翻译成计算机可以读懂的二进制语言,生成一个可执行程序(test.exe)然后通过运行环境将这个代码的结果输出出来。:将源代码程序被输⼊扫描器,扫描器的任务就是简单的进行词法分析,把代码中的字符分割成一系列的记号(关键字、标识符、字面量、特殊字符等)。多个.c文件单独经过编译出编译处理生产对应的目标文件,多个目标⽂件和链接库⼀起经过链接器处理生成最终的可执⾏程序。3.处理#include预编译指令,将包含的头文件的内容插入到该预编译指令的位置。
2024-03-02 20:52:39
343
原创 C语言中的文件与文件操作
当我们在写程序的时候经常需要重外部获取数据,例如:从键盘上输入,从文件中输入,从网络中输入等等,也需要将一些数据输出出来,例如:将数据打印在屏幕上,保存在文件,发送到网络上等等。当我们写完一个程序并关闭之后,再来打开代码还在,当我们写完一篇论文后,再打开,我们写的内容还在,这是因为我们把程序、论文保存在文件中。,为了方便程序员对各种设备进行方便的操作,我们抽象出了流的概念。我们知道写代码的时候会向内存开辟空间,数据会存储在内存中,可当程序关闭时,内存会回收,数据就会丢失,这时就可以使用文件将数据保存。
2024-02-28 23:10:38
1285
原创 结构体是个啥???
简单来说,当我们要来描述一个学生时,需要定义名字,身高,体重,性别,成绩等等,那单单使用int类型就定义不了名字这些,而使用char类型又定义不了身高,体重这些,而我们就可以根据需要在结构体定一多种类型定义不同类型的数据,结构体就是解决这个问题的,可以让我们自己创造合适的类型已适用不同场景。char类型占1个字节,short类型占2个字节,int类型和float类型占4个字节,double类型和long long类型占8个字节,那一个结构体占多少个字节?eg: 一个学生有名字,成绩,学号,年龄的信息。
2024-02-18 17:50:06
1633
1
原创 数据在内存中存储
0000000000000000000000000000001,红色为符号位,其余为数值位。而负整数的原码、反码和补码的表示方法不同。eg:5.5的二进制数为101.1,首先先把这个二进制数写成科学计数法的形式,先把小数点前移两位,再乘以他的倍数为1.011*原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。的原码、反码和补码都相同 eg:1的。对于32位的浮点数,S为0,M为1.011,E为2。S为1,M为1.011,E为2。
2024-02-04 00:37:46
372
1
原创 C语言中的一些内置函数
上面代码strlen(arr)这个就是向strlen函数传入arr的地址,arr为表示的是数组首元素的地址及是'a'的地址,由于字符串"abcdef"后面还有个'\0',所以计算的是从a到f的字符的数量总共有6个。strcmp(arr2, arr1)则返回大于0的数,在strcmp(arr2, arr3),由于arr1,arr2中的字符串一样返回0。strstr("ababdefabd", "abd")是在"ababdefabd"中找"abd",找到后返回"abd"在"ab。efabd"第一次出现的位置。
2024-02-01 00:01:49
860
原创 指针是个啥~~~!!!???
计算上CPU在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中。假设有一个指针变量p里存放着一个函数的地址,当函数调用完后,函数的空间就会释放,那p里面也就存放了一个已经释放空间的地址,当我们利用p去访问它时就会出错,这时的p就是野指针。1.指针变量未初始化(int* p)像括号的例子,定义一个指针变量p,但是没有给指针变量附一个地址,这样指针p就指向了一块未知的,随机的空间,这个指针p就是个野指针。野指针指的是指针指向的地址是未知的,指针指向了一个随机的未知的,错误的地址。
2023-12-01 21:07:01
37
1
原创 用C语言实现简易版--扫雷游戏
在一个9*9的方格内有10颗地雷,玩家要进行排雷,在9*9的方格中选择,如果选到地雷则炮炸,游戏结束,如果不是地雷,则会告诉玩家以选择的方位为中心的四周(3*3的方格)内有几颗地雷,玩家需要根据提示继续排雷,直到把所有非雷区域找出来则游戏胜利。printf("***** 1.开始游戏 *****\n");printf("***** 2.结束游戏 *****\n");printf("—————----扫雷游戏-----————\n");printf("选择错误,重新选择\n");
2023-11-10 15:59:12
98
1
原创 C语言的分支结构(if与switch语句)
在上述代码中,当a为8时执行case 8后面的语句,a为7时执行case 7后面的语句,当a为10时由于case 10后面没有语句,就会执行case 9后面的语句,(因为只有当代码遇到break时才会跳出switch语句,没有遇到break时就会一直执行case后面的语句)。在上述代码中,首先定义存储成绩变量的a,假设a为95,接着就将95/10(等于9),再将9赋值给a,接着swtich(9)就会找到case 9,并执行case 9后面的语句,打印出"case 9:printf("你的成绩为A\n");
2023-11-01 17:13:42
119
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人