JUC
文章平均质量分 97
主要介绍Java 高并发编程知识
爱吃芝士的土豆倪
世间不如意十之八九。如果没办法一次到位,就分阶段实现吧。
展开
-
真实并发编程问题-1.钉钉面试题
学完了并发编程,是否真的能够灵活应用其思想呢?实践才是检验真理的唯一标准,好记性不如烂笔头。下面就让我以我一个朋友社招面试钉钉的一道面试题来讲解下并发编程的实际应用吧。其实这个问题不仅仅想说一些解法的小细节,还是想说,其实这个面试题,更像是真实业务模型中抽取出来的,很偏向于业务开发,当我们学习完并发编程的时候,能够学习这样真实的业务模型,并能针对不同的场景进行分析,就能够触类旁通,更好的将并发编程的解决思路应用于实际问题的解决中去。原创 2023-12-19 19:42:13 · 1045 阅读 · 0 评论 -
程序员的护城河-并发编程
世间不如意十之八九。如果没办法一次到位,就分阶段实现吧。学习JUC是完善整个后端体系必不可少的一环,因为很多Java后端的中间件或者框架其本身内部大量的涉及到了JUC的部分,并且也可以在阅读JUC源码的过程中明白思想,其实思想都是互通的,例如ReentrantLock的原理本质上和Redisson 的原理是类似的,那么就可以迅速过度到分布式锁的使用中。原创 2023-11-20 17:10:00 · 1131 阅读 · 6 评论 -
剑指JUC原理-20.并发编程实践
LongAdder中最核心的思想就是利用空间来换时间,将热点value分散成一个Cell列表来承接并发的CAS,以此来提升性能。LongAdder的原理及实现都很简单,但其设计的思想值得我们品味和学习。原创 2023-11-18 18:52:00 · 887 阅读 · 0 评论 -
剑指JUC原理-19.线程安全集合
遗留的线程安全集合如 Hashtable , Vector (出现时间比较早,而且所有方法都是用synchronized修饰,并发性能比较低,时至今日有更好的实现,更好的替代)使用 Collections 装饰的线程安全集合,如:(将原本不安全的集合变成安全的集合)extends K,?传入的就是线程不安全的map,将其变成线程安全的本质上就是多加了一个synchronized 锁住了对象。原创 2023-11-18 15:28:01 · 394 阅读 · 0 评论 -
剑指JUC原理-18.同步协作
而"享元模式"下的实现需要手动管理线程的等待和唤醒,使用 wait 和 notify 的机制更为复杂,可读性较差。如果不一致,比如说线程池是 三个核心线程,那么当继续走for循环的时候,由于cyclicbarrier的特性,此时就是两个task1 执行完成了,而task2比较慢。这样有可能会影响最终的效果。假设其中 Thread-1,Thread-2,Thread-4 cas 竞争成功,而 Thread-0 和 Thread-3 竞争失败,进入 AQS 队列。,用来进行线程协作,等待线程满足某个计数。原创 2023-11-10 20:19:35 · 298 阅读 · 0 评论 -
剑指JUC原理-17.CompletableFuture
阻塞的方式和异步编程的设计理念相违背,而轮询的方式会消耗无畏的CPU资源。因此,JDK8设计出CompletableFuture异步任务结束时,会自动回调某个对象的方法;异步任务出错时,会自动回调某个对象的方法。原创 2023-11-10 10:09:37 · 366 阅读 · 0 评论 -
剑指JUC原理-16.读写锁
之前学读写锁,其实已经看到了读读可以并发,已经很快了,但是还不够快,读读并发的时候,底层还是用cas的方式去修改它的状态,读锁的高16位去修改它的状态,它还是性能上比不上不加锁,如果希望读取的性能达到这种极致,那么就可以使用StampedLock。其实该流程和 ReentrantLock 几乎是一样的,但是还是有一些区别的,比如state不太一样,因为state既要给读锁用,也要给写锁用,所以要将state分成两部分。😉 这次自己是老二,并且没有其他。原创 2023-11-09 20:14:35 · 650 阅读 · 0 评论 -
剑指JUC原理-15.ThreadLocal
从Java官方文档中的描述:ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是private static类型的,用于关联线程和线程上下文。我们可以得知 ThreadLocal 的作用是:提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂度。原创 2023-11-08 20:27:43 · 313 阅读 · 0 评论 -
剑指JUC原理-14.ReentrantLock原理
全称是 AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架用 state 属性来表示资源的状态(分独占模式和共享模式),子类需要定义如何维护这个状态,控制如何获取锁和释放锁getState - 获取 state 状态setState - 设置 state 状态compareAndSetState - cas 机制设置 state 状态独占模式是只有一个线程能够访问资源,而共享模式可以允许多个线程访问资源。原创 2023-11-07 14:39:08 · 498 阅读 · 0 评论 -
剑指JUC原理-13.线程池
让有限的工作线程(Worker Thread)来轮流异步处理无限多的任务。也可以将其归类为分工模式,它的典型实现就是线程池,也体现了经典设计模式中的享元模式。例如,海底捞的服务员(线程),轮流处理每位客人的点餐(任务),如果为每位客人都配一名专属的服务员,那么成本就太高了注意,不同任务类型应该使用不同的线程池,这样能够避免饥饿,并能提升效率例如,如果一个餐馆的工人既要招呼客人(任务类型A),又要到后厨做菜(任务类型B)显然效率不咋地,分成。原创 2023-11-06 17:19:43 · 369 阅读 · 0 评论 -
剑指JUC原理-12.手写简易版线程池思路
线程是一个系统资源,没创建一个新的线程就会占用一定的内存,会用栈内存,如果是高并发情况下,一下子来了很多任务,如果我为每个认为都创建一个新的线程,对内存的占用是非常大的,甚至可能会出现内存泄漏问题。自定义线程池其实包含几个组件:生产者,消费者,阻塞队列,两边的速率由阻塞队列等待。原创 2023-11-05 19:41:56 · 617 阅读 · 0 评论 -
剑指JUC原理-11.不可变设计
定义英文名称:Flyweight pattern. 当需要重用数量有限的同一类对象时(每次保护性拷贝都需要创建新的字符串,如果有取值相同的对象已经有了,那就可以重用这些对象,而不是每次都创建新的)原创 2023-11-04 19:52:40 · 262 阅读 · 0 评论 -
剑指JUC原理-9.Java无锁模型
Unsafe 对象提供了非常底层的,操作内存、线程的方法,Unsafe 对象不能直接调用,只能通过反射获得static {try {不要被名字所迷惑,名字虽然叫 Unsafe,但是这里并不是指什么线程安全的方面的不安全,而是指这个类比较底层,操作的都是内存,线程,不建议我们编程人员直接对它使用。原创 2023-11-03 22:09:44 · 652 阅读 · 0 评论 -
剑指JUC原理-10.并发编程大师的原子累加器底层优化原理(与人类的优秀灵魂对话)
如果加锁成功,又做了一遍检查,再次确保数组是不为空的,数组的长度是不为零的,然后又检查这个线程对应的那个数组中空的槽位是不是真的是null,是null的话代表着这个cell对象没有别人创建,那么前面创建的cell对象就可以存入数组的下标中去,如果不为空,说明有其他线程在数组的该下标下创建了cell对象,那前面的cell对象就白创建了,就再次回到循环中。这里面需要注意就是虽然cells大小是2,但是累加单元cell只创建了一个,还有一个是空着的,这也是懒惰初始化的关键,不到万不得已不会创建的。原创 2023-11-03 22:04:09 · 491 阅读 · 0 评论 -
剑指JUC原理-8.Java内存模型
Balking (犹豫)模式用在一个线程发现另一个线程或本线程已经做了某一件相同的事,那么本线程就无需再做了,直接结束返回。原创 2023-11-01 21:07:44 · 734 阅读 · 0 评论 -
剑指JUC原理-7.线程状态与ReentrantLock
在这里详细解读一下,说一下主体的流程,一开始三个线程同时执行 print,线程同时启动,首先争取锁,先假设一个最理想的情况就是syncWaitNotify.print(1, 2, “a”);这个实际的场景是这样的,首先每个线程都执行print方法,都分别获取到锁,然后都进入了await(),首先执行start方法,唤醒a的条件变量,输出,然后继续唤醒b的条件变量,按照这个顺序即可实现。当前线程等待时间超过了 n 毫秒,或t 线程运行结束,或调用了当前线程的 interrupt() 时,当前线程从。原创 2023-10-31 21:23:20 · 316 阅读 · 0 评论 -
剑指JUC原理-1.进程与线程
通过分析以上的时间性能,其实能说明很多的原因,比如说多核cpu情况下,多线程执行速度比单线程执行要快,而如果是单核,反而慢了,其实是因为多线程在单核下要进行时间片轮转,会产生一定的性能消耗。多线程可以让方法执行变为异步的(即不要巴巴干等着)比如说读取磁盘文件时,假设读取操作花费了 5 秒钟,如果没有线程调度机制,这 5 秒 cpu 什么都做不了,其它代码都得暂停… 2.也不是所有任务都需要拆分,比如任务二需要任务一的结果,任务的目的如果不同,谈拆分和效率没啥意思。原创 2023-10-24 19:18:46 · 357 阅读 · 1 评论 -
剑指JUC原理-2.线程
Thread是把线程和任务合并在了一起,Runnable是把线程和任务分开了用 Runnable 更容易与线程池等高级 API 配合用 Runnable 让任务类脱离了 Thread 继承体系,更灵活。原创 2023-10-25 21:57:20 · 265 阅读 · 2 评论 -
剑指JUC原理-3.线程常用方法及状态
直接调用run是在主线程中执行了run,并没有启用新的线程,而使用start是启动新的线程,通过新的线程简介执行了run中的代码。原创 2023-10-26 21:33:58 · 667 阅读 · 0 评论 -
剑指JUC原理-4.共享资源和线程安全性
但是不能像卖票问题一样,加一个锁就可以了,仔细分析一下发现 transfer中存在两个共享变量,money 和 target,如果对方法加synchronized ,实际上只对money这个共享变量上锁了,而 target并没有,解决办法其实就是对他们两个的父类上锁,也就是 锁对象是Account.class。2 1s 后 1 这个情况其实和前面说的一样,实际上是关于锁对象的概念,就是如果给静态方法加锁,实际上的锁对象是类本身,而不是实例对象,而给普通方法加锁,锁对象是实例对象,所以自然是这个结果。原创 2023-10-27 19:52:58 · 330 阅读 · 0 评论 -
剑指JUC原理-5.synchronized底层原理
重量级锁竞争的时候,还可以使用自旋(不阻塞,多进行几次循环)来进行优化,如果当前线程自旋成功(即这时候持锁线程已经退出了同步块,释放了锁),这时当前线程就可以避免阻塞(因为阻塞,线程会发生一次上下文切换,极大的浪费性能)。通过Klass Word,可以确定对象的类型,并进行动态分派,即在运行时根据对象的实际类型调用相应的方法。从头开始读 这段字节码:本质上就是获取锁,保存引用,然后讲锁对象的markword与monitor关联,然后执行锁中的内容,最终锁内容结束,释放并唤醒EntryList中的其他线程。原创 2023-10-28 18:23:42 · 594 阅读 · 0 评论 -
剑指JUC原理-6.wait notify
obj.wait()让进入 object 监视器的线程到 waitSet 等待在 object 上正在 waitSet 等待的线程中随机挑一个唤醒让 object 上正在 waitSet 等待的线程全部唤醒它们都是线程之间进行协作的手段,都属于 Object 对象的方法。必须获得此对象的锁,才能调用这几个方法log.debug("执行....");// 让线程在obj上一直等待下去log.debug("其它代码....");}).start();原创 2023-10-29 20:26:53 · 245 阅读 · 0 评论