并发编程学习
文章平均质量分 92
Mr_Wzzzz
这个作者很懒,什么都没留下…
展开
-
如何让多线程步调一致?
CountDownLatch和CyclicBarrier是Java并发包提供的两个非常应用的线程同步工具类,这两个工具类的用法区别在这里还是有必要再强调一下的。CountDownLatch主要用于解决一个线程等待多个线程的场景可以类比于旅游团长要等待所有的旅客到齐才能去下一个景点,而CyclicBarrier是一组线程之间互相等待,更像是几个驴友之间的不离不弃。原创 2023-08-18 22:29:53 · 216 阅读 · 0 评论 -
有没有比读写锁更快的锁
StampLock的使用看上去有点复杂,但是如果你能理解乐观所背后的原理,使用起来还是比较流畅的。原创 2023-08-17 22:33:29 · 253 阅读 · 0 评论 -
如何快速实现一个限流器
信号量在Java语言里面的名气并不算大,但是在其他语言里却很有知名度。Java在并发编程领域走的很快,重点支持的还是管程模型。管程模型理论上解决了信号量模型的一些不足,主要体现在易用性和工程化方面。原创 2023-08-14 22:39:22 · 188 阅读 · 0 评论 -
Dubbo如何用管程实现异步转同步
Lock & condition是管程的一种实现,所以能否用好lock和condition,要看你对管程模型理解怎么样。管程的技术前面我们已经专门写了一篇文章做介绍,你可以结合着来学,理论联系实践也更有助于加深理解。原创 2023-08-12 00:04:02 · 184 阅读 · 0 评论 -
隐藏在并发包中的管程
如果你细心观察,会发现我们创建的锁的具体类名是ReentrantLock,这个翻译过来叫做可重入锁,这个概念前面我们一直没有介绍过。所谓可重入锁,顾名思义指的是线程可以重复的获取同一把锁,如下面代码中。当线程T1执行到①处时,已经获取到了rtl,当在①处调用get方法时,会在②再次对所rtl执行加锁操作,此时如果。锁rtl是可重入的,那么线程T1可以再次加锁成功。如果锁rtl是不可重入的,那么线程T1此时会被阻塞。除了可重入锁,你可能还听过可重入函数,可重入函数怎么理解呢?原创 2023-08-11 21:02:32 · 29 阅读 · 0 评论 -
如何运用面向对象思想写好并发程序
利用面向对象思想编程编写并发程序一个关键点就是利用面向对象里的封装特性。由于篇幅原因,这里我只做了简单的介绍,详细你可以再借助相关资料进行定向学习。原创 2023-08-08 22:16:35 · 57 阅读 · 0 评论 -
为什么局部变量是线程安全的
调用栈是一个通用的计算机概念,所有的编程语言都会涉及到。Java调用栈相关的知识我并没有花费很大力气去深究,但是靠着那点C语言的知识稍微思考一下,基本上也就推断出来了。原创 2023-08-07 22:51:37 · 39 阅读 · 0 评论 -
创建多少线程才是合适的?
很多人都知道线程数不是越多越好,但是设置多少是合适的却又拿不定主意,其实只要把握一条原则就可以了,这条原则就是将硬件的性能发挥到极致。上面我们针对CPU密集型和I/O密集型计算场景都给出了理论上的最佳公式,这些公式背后的目标就是将硬件的性能发挥到极致。原创 2023-08-06 12:42:02 · 124 阅读 · 0 评论 -
Java线程的生命周期
理解Java线程的各种状态以及生命周期对于诊断多线程bug非常有帮助。多线程程序很难调试,出了bug基本上都是靠日志,靠线程dump来跟踪问题。分析线程dump的一个基本功就是分析线程状态,大部分的死锁、饥饿、活锁问题都是需要跟踪分析线程的状态,同时本文介绍的线程生命周期具有很强的通用性。对于学习其他语言的多线程编程也有很大帮助。原创 2023-08-04 23:13:12 · 38 阅读 · 0 评论 -
管程,并发编程的万能钥匙
不知道你是否曾考虑过这个问题:为什么Java在1.5之前仅仅提供了synchronized关键字及wait() notify() notifyAll()这三个看似从天而降的方法?在刚接触Java的时候,我以为它会提供信号量这种编程原语。因为操作系统原理课程告诉我用信号量能解决所有的并发问题,结果我发现不是。后来我找到了原因,Java采用的是管程技术,synchronized关键字及wait() notify() notifyAll()这三个方法都是管程的组成部分,而管程和信号量是等价的。原创 2023-08-03 23:04:00 · 41 阅读 · 0 评论 -
安全性、活跃性以及性能问题
并发编程是一个复杂的领技术领域,微观上涉及到了原子性问题、可见性问题和有序性问题,宏观则表现为安全性、活跃性以及性能问题。我们在设计并发程序的时候,主要是从宏观出发,也就是关注它的安全性、活跃性以及性能。安全性方面主要要注意数据竞争和竞态条件。活跃性方面需要注意死锁、活索、饥饿等问题。性能方面我们虽然介绍了两个方案,但是遇到具体问题还是要具体分析,根据特定的场景选择合适的数据结构和算法。原创 2023-08-02 21:13:38 · 35 阅读 · 0 评论 -
用“等待-通知“机制优化循环等待
等待-通知机制是一种非常普遍的线程间协作方式,工作中经常看到有同学使用轮询的方式来等待某个状态,很其实很多情况下都可以用我们今天的等待通知机制来优化。Java语言内置的synchronized配合wait() notify() notifyAll()这三个方法可以快速的实现这种机制,但它们的使用看上去还是有点复杂,所以你需要认真理解等待队列和wait() notify() notifyAll()的关系,最好用现实世界做个类比,这样有助于你的理解。原创 2023-08-01 22:42:50 · 32 阅读 · 0 评论 -
遇到死锁怎么办
当我们在编程世界里遇到问题时,应不局限于当下,可以换个思路向现实世界要答案,利用现实世界的模型来构思解决方案,这样往往能够让我们的方案更容易理解,也更能够看清楚问题的本质。但现实世界的模型有些细节往往会被我们忽略,因为在现实世界里,人太智能了,以至于有些细节显得不太重要。在转账模型中,我们为什么会忽视死锁的问题呢?主要是在现实世界中我们会交流。而且会很智能的交流,在编程世界里,两个线程是不会智能的交流的,所以在利用现实模型建模时,我们还要仔细比对现实世界和编程世界里的各个角色之间的差异。原创 2023-07-31 23:20:18 · 34 阅读 · 0 评论 -
互斥锁之如何用一把锁保护多个资源?
相信看完这篇文章,对于如何用一个锁保护多个资源就很有心得了,它的关键就是要分析多个资源之间的关系。如果资源之间没有关系,那就很好处理。每个资源一把锁就可以了,如果资源之间有关系,就要选择一个粒度更大的锁,这个锁能够覆盖所有相关的资源。除此之外,还要梳理出有哪些访问路径,所有访问路径都要设置合适的锁,这个过程可以类比一下门票管理。原子性的本质是什么?其实就是不可分割。不可分割只是外在的表现,其本质是多个资源间有一致性的,要求操作的中间状态对外不可见。原创 2023-07-27 23:16:39 · 62 阅读 · 0 评论 -
互斥锁:解决原子性问题
互斥锁,在并发领域的知名度极高,只要有了并发问题,大家首先容易想到的就是加锁,因为大家都知道加锁能够保证执行临界区代码的互斥性。这样理解虽然正确,但却不能够知道你真正用好互斥锁。临界区的代码是操作受保护资源的路径,类似于球场的入口,入口一定要检票,也就是要加锁,但不是随便一把锁都能有效,所以必须深入分析锁定的对象和受保护资源的关系,综合考虑受保护资源的访问路径,多方考量才能用好互斥锁。原创 2023-07-25 22:53:34 · 42 阅读 · 0 评论 -
Java内存模型
我们在上期聊到了导致可见性的原因是缓存,导致有序性的原因是编译优化,那么解决可见性、有序性的最直接的方法就是禁用缓存和编译优化。但是这样问题虽然解决了,但是我们的性能就堪忧了。那么较为合理的方案就是按需禁用缓存以及编译优化。但是如何做到按需禁用呢?对于并发程序核实禁用缓存以及编译优化只有程序员知道,那所谓按需禁用其实就是按照程序员的要求来禁用。所以,为了解决可见性和有序性的问题,只需要提供给程序员按需禁用缓存和编译优化的方法即可。原创 2023-07-23 13:24:33 · 38 阅读 · 0 评论 -
可见性,原子性,有序性问题
只有深刻理解可见性、原子性、有序性在并发场景下的原理,才能理解许多并发bug的产生。原创 2023-07-20 23:47:10 · 56 阅读 · 0 评论