![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
多线程
文章平均质量分 96
翁佳明
只有一种英雄主义
展开
-
【多线程】JUC的常见类 | Callable接口 | ReentranLock | 线程安全的集合类
发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去. 扩容期间, 新老数组同时存在. 后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小部分元素. 搬完最后一个元素再把老数组删掉. 这个期间, 插入只往新数组加. 这个期间, 查找需要同时查新数组和老数组。可以通过配置文件来描述配置的详细内容(文件本身不是很大),配置的内容就会被读到内存中,再由其他的线程,来读取这里的内容。只有在操作同一个链表上的内容时,才会发生线程安全问题。原创 2024-04-22 23:23:34 · 859 阅读 · 3 评论 -
【多线程】synchronized原理 | 锁升级| 锁消除 | 锁粗化 | 信号量 | CountDownLatch
在实际使用的过程中,如果发现锁冲突的情况比较多,synchronized就会升级成悲观锁(也就是重量级锁,基于挂起等待的方式实现)。当锁冲突出现的时候,偏向锁就会升级成轻量级锁,进行真正的加锁操作。 迪杰斯特拉提出的信号量,同时,他也是一位荷兰数学家,在数据结构的图中,要想获取两点之间的最短路径,就可以用迪杰斯特拉算法。线程池,优化的是创建新线程的效率(优化”找下一任“的效率),提前就创建好,直接拿来用,无缝衔接。偏向锁 的核心思想,就是“懒汉模式” 的一种体现,能不加锁就不加锁,因为加锁就意味着开销。原创 2024-04-22 23:18:47 · 869 阅读 · 0 评论 -
【多线程】CAS的应用 | CAS的概念 | 实现原子类 | 实现自旋锁 | ABA问题
Compare and swap 比较并交换。比较交换的是 内存 和 寄存器比如此时有一个内存 : M。还有两个寄存器A,B CAS ( M , A , B ) :如果M和A的值相同的话,就把M和B的值进行交换(交换的目的是为了把B赋值给M,M = B),同时整个操作返回 true。如果M和A的值不同的话,无事发生,同时整个操作返回false。//伪代码:CAS其实是一个CPU指令,一个CPU指令,就可以完成上述比较交换的逻辑。单个的CPU指令是原子的。原创 2024-04-21 22:00:53 · 933 阅读 · 0 评论 -
【多线程】常见的锁策略 | 乐观锁 | 轻量级锁 | 重量级锁 | 自旋锁 | 挂起等待锁 | 读写锁 | 可重入锁 | 公平锁
可重入锁,锁里面保存了当前是哪个线程加上的锁,同时维护了一个计数器,所以第二次加锁的时候,不会触发阻塞等待,而是自增计数器。要借助系统api来实现,一旦出现锁竞争,就会在内核中触发一系列动作(比如让这个线程进入阻塞状态,暂时不参与CPU的调度。 当很多线程去尝试加一把锁的时候,一个线程拿到锁,其他线程就会阻塞等待。 轻量级锁是指,锁的开销比较小,消耗的资源少。乐观锁通常是轻量级锁,可能存在特例,不绝对。是“锁的一种特性”,是一类锁,而不是具体的锁。 重量级锁是指,锁的开销比较大,消耗的资源多。原创 2024-04-21 21:57:17 · 672 阅读 · 0 评论 -
【多线程】定时器 | 线程池 | 实现MyTimer | 实现MyThreadPoll | 工厂模式 | 构造方法 | 参数种类
假设一个线程的所有代码都是CPU密集型代码,线程池中的线程数量不应该超过N(CPU核心数),设置的比N大,cpu吃满了,无法提高效率,此时添加更多的线程反而增加调度的开销。换句话说,timer当中的任务,是有当中的扫描线程来执行的。所以在第一次判断时间时,在else中,当任务时间还没到的时候,进行wait阻塞,此时线程不会在CPU上调度,避免了忙等。 假设一个线程的所有代码都是IO密集型的,这个时候不吃CPU,此时设置的线程数,就可以超过N.一个核心可以通过调度的方式,来并发执行。原创 2024-04-18 21:13:54 · 1577 阅读 · 0 评论 -
【多线程】阻塞队列 | put()方法 | take()方法 | 生产者-消费者模式 |实现阻塞队列
在这种情况下:高峰时段,一旦客户端发起的请求量非常多时,每个A收到的请求,都会立即发给B。 使用wait时,要考虑wait是notify唤醒的,还是通过Interrupt唤醒的。wait方法除了使用notify()方法进行唤醒,还可以通过interrupt()方法,来中断wait的状态。在出队的时候,当size–后,队列中有位置了,调用notify()方法,对阻塞的put方法进行唤醒。在入队时,当size++后,队列不为空了,调用notify()方法,对阻塞的take方法进行唤醒。原创 2024-04-16 21:29:54 · 938 阅读 · 0 评论 -
【多线程】单例模式 | 饿汉模式 | 懒汉模式 | 指令重排序问题
单例模式三步走:1.懒汉模式下的双重if嵌套2.用Synchronized对第二个if和后续是实例化操作进行加锁3.用volatile修饰实例,禁止指令重排序。面试遇到的话,人生如戏全靠演技,要适当藏拙,一步一步优化。从单线程的懒汉模式,到加锁,再到指令重排序点击移步博客主页,欢迎光临~原创 2024-04-15 19:39:32 · 1187 阅读 · 0 评论 -
【多线程】 synchronized关键字 | 可重入锁 | 死锁 | volatile关键字 | 内存可见性问题 |wait¬ify方法|
岁月不居,时节如流。仅以此文,为白女士送上生日祝福。生日快乐,哥们。原创 2024-04-11 22:22:48 · 1485 阅读 · 0 评论 -
【多线程】Thread的常见属性 | 终止线程 | 等待线程 | 休眠线程 | 线程安全
有的代码在单线程环境下,可以正常执行。但是同样的代码,让多个线程去同时执行,就有可能出现BUG。这类问题就是线程安全问题/线程不安全。//对变量自增50000次i < 50000;});i < 50000;});t1.start();t2.start();t1.join();t2.join();//没有join的话,线程还没自增完,就会打印count上面的代码在并发执行时,构成了线程安全问题。原创 2024-04-10 21:07:49 · 963 阅读 · 0 评论 -
【多线程】线程(线程的概念+线程的创建)
主要消耗在申请资源上面。 验证了每一个线程都是一个独立的执行流,在主线程中,遇到t线程时,兵分两路。为了跨平台,Java又对系统的API进行了封装(Thread类),通过Thread类创建Thread对象,从而操作系统内部的进程。Runnable表示的是一个“可以运行的任务”,这个任务是交给线程负责执行,还是交给其他的实体执行。5.进程之间具有独立性,一个进程出问题,不影响其他进程,不相互干扰。4.进程和进程之间不共享内存空间,同一个进程的线程之间共享同一份内存空间和文件资源,省去了申请资源的开销。原创 2024-04-09 21:35:44 · 995 阅读 · 0 评论 -
【多线程】进程(进程的概念+进程的管理+PCB(进程控制块)+进程的调度+进程的独立性)
2.一个exe文件,就包含了指令和数据,运行exe,操作系统就会把指令和数据加载到内存中(内存地址),CPU先从内存中取指令,然后执行指令。 记账信息会记录,当前进程持有CPU的情况(记录在CPU中执行了多久),可以作为操作系统调度进程的参考依据,从而对资源分配进行调整。2.进程的内存空间,需要有专门的区域存储要执行的指令,以及指令依赖的数据。进程从CPU离开之前,需要保存现场,把当前CPU中各种寄存器的状态,都记录到内存中(存档)不同系统的API是不同的,在Java中,系统的API会被JVM进行封装。原创 2024-04-08 21:44:39 · 1216 阅读 · 0 评论