- 博客(21)
- 收藏
- 关注
原创 锁策略,synchronized和CAS的锁优化
某个线程没有锁的是时候就是一个无锁的状态,当这个线程获取到synchnorized时会变成偏向锁,但是不会真正的加锁,只是这个锁会记录目前是哪个线程获取到这个锁,只是做一个标记(不会产生任何的开销,非常快);指的是所有等待线程获取锁的机会公平与否,如果是按照先来回到的顺序,那么这个锁就是公平锁,如果等待的线程获取锁的概率是均等的,这个锁就是不公平锁,这是由以前发明锁的大佬定义的,如果另一个时间线定义的是概率均等是公平锁,就又是另一个说法;指的是锁的粒度,这个锁要完成的任务越多,代码量越多,粒度就越大;
2024-07-13 15:43:34 822
原创 总结线程池
最大核心线程数最大线程数(核心线程数+非核心线程数)非核心线程允许存在的最大空闲时间keepALiveTime的时间单位,时分秒之类要执行的任务线程队列创建线程的工厂类,使用不同的工厂相当于对线程池进行不同的初始化拒绝策略。
2024-07-13 10:58:17 392
原创 线程安全问题的原因与解决方案
为了可以更好的解释,给大家看一个错误的代码,问题是两个线程修改同一个变量,每个线程每次对变量+1循环50000次;测试发现,结果都是错误的;
2024-06-17 23:30:05 804
原创 两种单例模式(保证线程安全)
单例模式也叫单个实例,也就是这个类只有且只能有一个实例对象,这样一个类就叫做“单例”;单例模式有很多种,这里只介绍“饿汉模式”和“懒汉模式”两种;
2024-06-17 00:33:15 1140 1
原创 Java 线程的几种状态
基于六种线程的状态的学习,将来我们在线程出现问题之后我们就就可以借助第三方工具,就可以关注线程的状态,通过状态就能看到线程是在哪一行被卡住(阻塞)了,原因大概是什么;六种状态的转换。
2024-06-07 22:02:57 821
原创 Thread类中run和start的区别
run方法是描述这个线程是要干什么,比如我的这个线程就是让它每间隔一秒就打印一次”Hello thread“;而start()就是让这个实例化的线程跑起来,两个从中文意思上看好像都是让线程执行起来,但是这个方法是完全不同的;举个例子更好理解:run方法就是放学了之后你把作业是什么写下来在本子上,而start()方法就是开始写作业;再看代码:在main方法,也就是main主线程中new了Mythread的对象,并调用start();先看代码:继承Thread创建了一个线程,重写了run方法;
2024-06-03 22:19:58 189
原创 进程(process)与线程(thread)
主要是如果针对每一个客户端执行后连接上服务器,服务器就会给创建一个进程供客户端使用,客户客户端运行结束,服务器就把进程销毁,咋一看这样好像没什么问题,但是如果这个服务器频繁的有客户端来来去去,就要频繁的创建销毁进程,频繁的分配资源/释放资源,虽然不至于拖垮服务器,但是会使服务器的响应速度变慢;同个进程中的所有线程的共用内存指针和文件描述表;但是每一个线程是不同的cpu上调度的,但是同一个进程中的线程A中new一个对象,线程B是可以访问到的,线程B中打开一个文件,A也是可以打开的;PCB(描述线程的)
2024-06-03 18:56:10 287
原创 进程调度1.0
进程的执行是抢占式,进程的运行需要占有CPU资源,有的进程需要更多的CPU资源,有的进程相对就不需要那么多,就需要适当的分配好CPU资源,设置优先级高的分配更多的资源,设置优先级低的分配少的资源,优先级的高低就可以决定进程运行的次序,优先级高的可能反复在CPU上执行;查看任务管理器的进程,我们可以看到又非常多的进程,每个进程有都需要执行,执行就需要占用cpu资源,但是cpu的资源又有限,例如我的电脑只有16个逻辑处理器,就意味着我的电脑只能同时处理16个进程,那其他进程怎么办呢?
2024-06-02 23:01:57 343
原创 TreeMap和TreeSet
这里用替换法作为方法,即找到cur左子树的最大值或者右子树的最小值p节点,将p值赋给 cur,删除掉p, 这里选择找左子树的最大值作为分享。3.1 p==tp.right,这里选择删除3,左子树最大值就是2(这里由于2是最大的,所以2不会有右子树,但 是可以有左子树),就像链表的节点的一样,只不过存储的Key-Value两个值的键值对,该内部类中主要提供了 的获取,value的设置以及Key的比较方式。而Map中存储的就是key-value的键值对,Set中只存储了Key。
2024-04-24 13:05:55 556
原创 优先级队列 PriorityQueue 模拟实现
优先级队列实际是小堆,根据不同的比较方法实现小堆,也可以根据自己的需要重写比较方法,从而实现自己想要的优先级队列,获取想要的数据,接下来将会用整数模拟实现一个优先级队列;//交换第一个元素和最后一个元素,出队最后一个元素,//交换上去的元素,即放在的元素向下调整。usedSize--;//插入的元素的元素个数减一。这里我的优先是优先获取最小的元素,保证出队的永远是现存的数据里最小的;再者就是出队元素,优先队列出的就是最小的或者最大的看自己的选择。* @param root 是每棵子树的根节点的下标。
2024-03-22 16:06:04 1123 1
原创 建堆入队元素必用向上调整方法
while(parent>=0){ //一直向上调整,直到parent<0不存在为止。//父亲节点的下标由孩子的下标可推出,以此循环。//parent为child的父亲节点。if(elem[child]<elem[parent]){ //如果孩子节点的值小于父亲节点。private void shiftUp(int child) { //child为插入的元素的下标。//右孩子小于左孩子,child++,是的child刚好指向小的那一个。
2024-03-22 15:28:38 578 1
原创 建堆必须用到的向下调整方法
找到他的左右孩子的最小的一个child,如果父节点parent小于这个child节点,就不交换,这个父节点就向下调整结束;如果父节点parent大于child就交换,此时父节点就变成子节点,再以该节点为父节点,找到他的两个孩子节点中的较小的一个,如果父节点parent小于这个child节点,就不交换,这个父节点就向下调整结束;采用向下调整,并不是从第一个元素开始向下调整,而是从下往上第一个非叶子节点开始,也就是如图的25,之后就是49,18,34,28,27,65;
2024-03-22 13:50:42 276 1
原创 内部类------实例内部类
1.实例内部类不允许存在静态变量,除非该变量被final修饰。2.实例化实例内部类需要通过实例化外部类,通过外部类对象实例化内部类对象,注意格式不要与 静态内部类的实例化混淆。3.外部类的任何成员都可以被实例化内部类访问。4.要分别访问外部类和内部类地同名成员,仅仅只是变量名,会采取就近原则,要用外部类对象.变量和this.变量名区别。5.在外部类中无法直接访问内部类的成员,必须通过内部类的实例化对象。
2023-11-16 16:59:14 34 1
原创 文件操作(下)
/此代码会先创建一个文件,等待一秒后会将字符串加载进缓冲区,此后在十秒的睡眠时间中,你可以看到创建的文件的大小是0kb,fflush后会将缓冲区的字符串全部加载进文件,你可以观察到文件大小变成1kb。因为有缓冲区的存在,C语在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。牢记:在⽂件读取过程中,不能⽤feof函数的返回值直接来判断⽂件的是否结束。二进制文件读取是否结束,要根据返回值是否小于要读取的个数;1.文件读取结束的判定。1.文件读取结束的判定。当文件读取结束的时候。
2023-10-26 14:27:07 37 1
原创 文件操作(中)
1.文件的顺序读写1.文件的顺序读写1.1顺序读写的函数介绍ps:关于我的个人理解,输入可以理解为读取,从文件里读取,从键盘上读取(输入);输出可以理解为就是输出,将程序中编写的输出到屏幕,输出写入到文件中;具体我给出下面的代码供大家理解;1.1.1.1由于这里是一“r”的方式打开文件,如果在绝对路径没有要操作的文件,就会报错,如下图1.1.1.2如果要操作的文件且该文件已经保存了99,fgetc就会从文件中读取一个字符,并返回该字符的ASCII码值,9的ASCII码值为57;
2023-10-26 00:27:53 29
原创 文件操作(上)
程序文件一般包括源程序文件(.c为后缀),目标文件(.obj)(linux系统是.o为后缀),可执行文件(.exe为后缀);c语言中,我们在打开文件的时候,会使用FILE* 指针来指向要操作的文件,以此来建立指针变量和文件的关系。顾名思义就是该文件中的内容都是二进制的形式存在,在我们看来都是乱码,以下就是一份二进制文件。一般指程序运行需要的从中获取数据的文件,或者程序输出内容,可供保存数据的文件。• stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊。便的操作,我们抽象出了流的概念,我们可以。
2023-10-25 18:38:07 49 2
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人