- 博客(29)
- 收藏
- 关注
原创 线程安全的集合类
如果修改同一个链表上的两个元素,可能就有线程安全问题,比如把这俩元素插入同一元素后面就可能产生竞争。效率更高,按照桶级别进行加锁,而不是给整个哈希加一个全局锁,有效降低锁冲突的概率。如果修改的两个元素,在不同链表上,本身就不涉及线程安全问题(修改不同变量)服务器代码中的其他逻辑就会读取这些数组/哈希中的值,不会修改。确保读取过程中,要么读到的是旧版数据,要么读到的是新版数据。把旧哈希中的所有元素搬运到新的哈希中(元素很多,耗时很长)服务器就会创建新的数组/哈希,加载新的配置。
2024-10-31 21:13:19 383
原创 CAS的ABA问题
什么是 CASCAS: 全称Compare and swap,字⾯意思:”⽐较并交换“,⼀个 CAS 涉及到以下操作:我们假设内存中的原数据V,旧的预期值A,需要修改的新值B。1.⽐较 A 与 V 是否相等。(⽐较)2.如果⽐较相等,将 B 写⼊ V。(交换)3.返回操作是否成功。判定内存中的值和寄存器1的值是否一致如果一致,就把内存中的值和寄存器2进行交换但是只关心交换后内存中的值,不关心寄存器2的值此处可以把这样的操作理解成赋值本质上是交换,基于交换实现了赋值。
2024-10-29 22:09:30 937
原创 常见的锁策略
如果后续有其他线程来竞争该锁(刚才已经在锁对象中记录了当前锁属于哪个线程了, 很容易识别当前 申请锁的线程是不是之前记录的线程), 那就取消原来的偏向锁状态, 进⼊⼀般的轻量级锁状态.假设三个线程 A, B, C. A 先尝试获取锁, 获取成功. 然后 B 再尝试获取锁, 获取失败, 阻塞等待;公平锁: 遵守 "先来后到". B ⽐ C 先来的. 当 A 释放锁的之后, B 就能先于 C 获取到锁.如果获取锁失败, ⽴即再尝试获取锁, ⽆限循环, 直到获取到锁为⽌. 第⼀次获取锁失败, 第⼆次的尝试。
2024-10-27 22:12:53 559
原创 Java【多线程】定时器
定时器也是软件开发中的⼀个重要组件. 类似于⼀个 "闹钟". 达到⼀个设定的时间之后, 就执⾏某个指定 好的代码.包含两个参数. 第⼀个参数指定即将要执⾏的任务代码, 第⼆个参数指定多⻓时间之后。标准库中提供了⼀个 Timer 类. Timer 类的核⼼⽅法为。和线程池一样,timer中也包含前台线程阻止进程结束。4.额外创建一个线程,负责执行队列中的任务。2.定时器中,能够管理多个任务的。1.创建一个类,表示一个任务。3.实现schedule方法。核心还是重写run方法。把任务添加到队列即可。
2024-10-27 20:30:47 276
原创 Java【多线程】线程池
(选择使用数组/链表,指定capacity,指定是否要带有优先级/比较规则,线程池,本质上也是生产者消费者模型,调用submit就是在生产任务,线程池里的线程就是在消费任务)在Java中,线程池是一种管理和复用线程的机制,可以有效地减少线程创建和销毁的开销,提高程序的性能和资源利用率。(至少有多少个线程,线程池一创建,这些线程也要随之创建,直到整个线程池销毁,这些线程才会销毁)(也是一种设计模式,和单例模式是并列的关系,用来弥补构造方法的缺陷)统一的构造并初始化线程。此时线程池里的线程就会执行这样的任务。
2024-10-27 18:28:01 874
原创 信号量(Semaphore)
信号量是一种用于控制对共享资源访问的同步工具,它允许多个线程同时访问一个资源,但限制了同时访问该资源的线程数量。在 Java 中,信号量由类实现,提供了获取和释放信号量的方法。通过使用信号量,可以有效地管理并发访问的资源,避免资源竞争问题。
2024-10-24 22:47:32 744
原创 Java【多线程】阻塞队列
put插入元素的时候判定如果队列满了就进行wait(注意,要在循环中进行wait,被唤醒时不一定队列就不满了,因为同时可能是唤醒了多个线程)1.队列为空,尝试出队列,出队列操作就会阻塞,阻塞到其他线程添加元素为止。2.队列为满,尝试入队列,入队列操作就会阻塞,阻塞到其他线程取走元素为止。take取出的时候,判定如果队列为空就进行wait(也是循环wait)此时需要更多的机器进行部署,生产环境的结构会更复杂,管理起来更麻烦。put方法用于阻塞式的入队列,take用于阻塞式的出队列。
2024-10-22 21:52:21 708
原创 Java【多线程】单例模式
线程安全问题发⽣在⾸次创建实例时. 如果在多个线程中同时调⽤ getInstance ⽅法, 就可能导致创建 出多个实例。单例模式(单个实例/对象),就是设计模式中一种非常典型的模式,也是比较简当的模式,还是校招中最容易被考到的设计模式。加锁 / 解锁是⼀件开销⽐较⾼的事情. ⽽懒汉模式的线程不安全只是发⽣在⾸次创建实例的时候. 因。当这个实例创建完了之后, 其他竞争到锁的线程就被⾥层 if 挡住了. 也就不会继续创建其他实例。类加载的时候不创建实例. 第⼀次使⽤的时候才创建实例.
2024-10-21 21:35:14 751
原创 Java【多线程】wait和notify
由于线程之间是抢占式执⾏的, 因此线程之间执⾏的先后顺序难以预知.但是实际开发中有时候我们希望合理的协调多个线程之间的执⾏先后顺序.
2024-10-19 20:34:47 757
原创 Java【多线程】volatile关键字
每个线程,有一个自己的“工作内存”work memory(cpu的寄存器),同时这些线程共享同一个“主内存”main memory 当一个线程循环进行上述读取变量操作的时候,就会把主内存中的数据,拷贝到该线程的工作内存中,后续另一个线程修改,也是先修改自己的工作内存,拷贝主内存里,由于第一个线程仍然在读自己的工作内存,因此感知不到主内存的变化。编译器虽然声称优化操作,是能够保证逻辑不变,尤其是在多线程的程序中,编译器的判断可能出现失误,可能导致编译器的优化,是优化后的逻辑,和优化前的逻辑出现细节上的偏差。
2024-10-16 21:51:28 718
原创 Java【多线程】线程安全问题
而是禁止其他线程重新加上这个锁避免其他线程的操作在当前线程的执行过程中插队。反之如果一个代码在多线程并发执行的环境下也不会出现类似于上述的bug。多个线程针对同一个锁对象加锁才会产生互斥(锁冲突/锁竞争)cpu执行这三条指令的过程中,随时可能触发线程的调度切换。2.synchronized()指定的锁对象也得合适。执行任何一个指令的过程中都可能触发上述线程切换操作。当前bug是由于多线程的并发执行代码引起的bug。通过加锁操作让不是原子的操作打包成原子的操作。synchronized(锁对象){//加锁。
2024-10-14 21:36:49 902
原创 Java【多线程】Thread类常见方法
写了sleep(0)意味着让当前的线程放弃cpu资源(把cpu让出来给别人更多的执行机会,等待操作系统重新调度。当前main这里的方法都执行完了,对应的isFinished就销毁了。因为线程的调度是不可控的所以这个方法只能保证实际休眠时间是大于等于参数设置的休眠时间。在c++的实现中内部就会判断当前是哪个操作系统,并且调用对应系统的api来创建线程。java的Thread对象中提供了现成的变量,直接进行判定,不需要自己创建了。java的做法是,把被捕获的变量给拷贝一份,拷贝给lambda里面。
2024-10-12 23:37:02 937
原创 Java【多线程】Thread几个常见属性
在idea中运行一个Java代码通过idea进程又创建出一个新的java进程(这两进程是有父子关系)java 代码中创建的Thread对象,和系统中的进程是一一对应的关系。(可能存在,thread对象还存活,但是系统中的线程已经销毁的情况)但是,thread对象的生命周期和系统中线程的生命周期是不同的。(即使他们继续存在,如果进程要结束了,他们也随之结束了)自己代码创建的线程比如Main线程默认是前台线程。主线程第四次打印,和t线程的结束,谁先谁后不一定。这些jvm自带的线程,他们的存在,
2024-10-11 20:45:27 259
原创 Java【多线程】创建线程写法
线程要执行的任务的定义是放到Thread里面,还是放到外面(Runnable中)从而后续如果变更代码.(比如不通过线程执行这个任务,通过其他方式..)如果有一天需要把这里的任务,通过其他方式执行(不使用多线程了)run()线程的入口方法,新的线程启动了,就要执行这里的代码。run方法不需要手动调用,新的线程创建好了之后,自动的去执行。创建了一个匿名的函数式接口的子类,并且创建出对应的实例。使用Runnable,任务和线程概念是分离的。就是一个任务,就是一段要执行的逻辑。最主要的用途,就是作为“回调函数”
2024-10-09 21:11:25 407
原创 LCR 025.两数相加II
来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。如果输入链表不能修改该如何处理?换句话说,不能对列表中的节点进行翻转。可以假设除了数字 0 之外,这两个数字都不会以零开头。
2024-09-28 22:53:31 189
原创 进程和线程的区别和联系
为了让业务更快的办理好,张三⼜找来两 位同事李四、王五⼀起来帮助他,三个⼈分别负责⼀个事情,分别申请⼀个号码进⾏排队,⾃此就有 了三个执⾏流共同完成任务,但本质上他们都是为了办理⼀家公司的业务。进程是操作系统对⼀个正在运⾏的程序的⼀种抽象,换⾔之,可以把进程看做程序的⼀次运⾏过程;⼀个线程就是⼀个 "执⾏流". 每个线程之间都可以按照顺序执⾏⾃⼰的代码. 多个线程之间 "同时" 执⾏着多份代码.⼀个进程挂了⼀般不会影响到其他进程. 但是⼀个线程挂了, 可能把同进程内的其他线程⼀起带⾛(整个进程崩溃).
2024-09-28 22:08:06 566
原创 692.前k个高频单词
"the", "is", "sunny" 和 "day" 是出现次数最多的四个单词,返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,"i" 和 "love" 为出现次数最多的两个单词,均为2次。注意,按字母顺序 "i" 在 "love" 之前。出现次数依次为 4, 3, 2 和 1 次。个出现次数最多的单词。
2024-07-24 21:43:29 380
原创 StringBuilder和StringBuffer
比较重要的一点,在StringBuffer的append方法中多了synchronized关键字,进入synchronized修饰的代码块,相当于加锁,多线程情况下可以保证线程安全,StringBuilder则没有。.在append方法中StringBuffer和StringBuilder的返回值是this,说明是在原有的字符串上修改的。如果要想互相转换,可以采用如下原则。的不可更改特性,为了方便字符串的修改,这两个类大部分功能是相同的,频繁修改字符串的情况考虑使用。即尾插,在尾部追加,相当于。
2024-05-30 21:35:06 789
原创 387.字符串中的第一个唯一字符
先定义一个count数组,char一个ch拿到s.charAt遍历字符串的每一个元素,然后ch对应下标的元素++;再遍历一遍字符串,如果count中ch对应下标的元素值等于1说明找到了,那么返回i下标;它的第一个不重复的字符,并返回它的索引。代码走完没找到则返回-1;
2024-05-30 20:06:45 172
原创 简单例子实现多态
所以很明显,同样是eat方法,在不同的对象上表现却不同 ,在dog对象上是吃骨头,在bird上是吃米粒,另一个act方法同理。多态即同一行为在不同的对象上会产生不同的形态,比如做同一道题,在不同的人身上就有不同的做法。实例化两个对象,这里我使用了向上转型,然后通过父类引用调用子类和父类重写的两个方法。然后创建两个子类dog和bird分别继承Animal,并重写父类的两个方法。多态是一种思想,要理解多态首先要理解继承,重写,向上转型,动态绑定。我先创建一个父类对象Animal,
2024-05-26 01:35:30 296
原创 继承问题,代码的执行顺序
本题中z类继承x类,先从main方法开始,由于没有静态代码块所以先执行父类的实例也就是x类中的Y y=new Y();然后跳转到classY执行Y的构造,打印Y,然后执行class x的构造,打印x,然后执行子类class z 的实例,Y y=new Y();然后子类class z的构造,打印z,结果输出yxyz,故选c。本题考察代码的执行顺序,在继承层次上首先要记住三个点,静态,实例,构造,具体来说就是先执行父类的静态和子类的静态,然后执行父类的实例,父类的构造,最后子类的实例,子类的构造,
2024-05-15 22:29:33 244 1
原创 递归求解汉诺塔问题
大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。然后执行一次move,最后还要再调用一次hanoi,将剩下的n-1个盘子从b柱移动到c柱。其中定义了三个柱子,分别是a,b,c柱,a柱表示起始位置,b柱表中转位,c表目标位置。if(n==1)表示递归方法的结束条件,当只有一个盘子时,直接将其 移动到目标位置,如果有一个以上的盘子那么先将其上面的n-1个盘子从起始位置a通过c中转移动到b,
2024-04-29 21:24:03 439
原创 求斐波那契数列第n项的两种方法
(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称“兔子数列”,其数值为:1、1、2、3、5、8、13、21、34……的方法定z义:F(0)=1,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)斐波那契数列(Fibonacci sequence),又称黄金分割数列 [1],因数学家莱昂纳多·那么这就是关于求斐波那契数列第n项的两种算法,你更支持哪一种呢。我勒个豆,求斐波那契第40项要运行102334155次。这样的话代码的运行效率就低了。
2024-04-27 23:00:24 959 1
原创 输出0~99999的水仙花数,四叶玫瑰数,五角星数...
(Armstrong number),水仙花数是指一个 3 位数,它的每个数位上的数字的 3次幂之和等于它本身。九位的九九重阳数共有4个: 146511208,472335975,534494836,912985153;七位的北斗七星数共有4个:1741725,4210818,9800817,9926315;八位的八仙数共有3个:24678050,24678051,88593477;五位的五角星数共有3个:54748,92727,93084;三位的水仙花数共有4个:153,370,371,407;
2024-04-27 22:04:59 258
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人