
J.U.C
文章平均质量分 93
鲁班大师撸源码
这个作者很懒,什么都没留下…
展开
-
10 _ Java线程(中):创建多少线程才是合适的?
在Java领域,实现并发程序的主要手段就是多线程,使用多线程还是比较简单的,但是使用多少个线程却是个困难的问题。工作中,经常有人问,“各种线程池的线程数量调整成多少是合适的?”或者“Tomcat的线程数、Jdbc连接池的连接数是多少?”等等。那我们应该如何设置合适的线程数呢?要解决这个问题,首先要分析以下两个问题:为什么要使用多线程?多线程的应用场景有哪些?为什么要使用多线程?使用多线程,本质上就是提升程序性能。不过此刻谈到的性能,可能在你脑海里还是比较笼统的,基本上就是快、快、快,这种无法度量的感.原创 2021-11-30 21:13:02 · 1610 阅读 · 0 评论 -
09 _ Java线程(上):Java线程的生命周期
在Java领域,实现并发程序的主要手段就是多线程。线程是操作系统里的一个概念,虽然各种不同的开发语言如Java、C#等都对其进行了封装,但是万变不离操作系统。Java语言里的线程本质上就是操作系统的线程,它们是一一对应的。在操作系统层面,线程也有“生老病死”,专业的说法叫有生命周期。对于有生命周期的事物,要学好它,思路非常简单,只要能搞懂生命周期中各个节点的状态转换机制就可以了。虽然不同的开发语言对于操作系统线程进行了不同的封装,但是对于线程的生命周期这部分,基本上是雷同的。所以,我们可以先来了解一下通用.原创 2021-11-30 21:12:31 · 169 阅读 · 0 评论 -
08 _ 管程:并发编程的万能钥匙
并发编程这个技术领域已经发展了半个世纪了,相关的理论和技术纷繁复杂。那有没有一种核心技术可以很方便地解决我们的并发问题呢?这个问题如果让我选择,我一定会选择管程技术。Java语言在1.5之前,提供的唯一的并发原语就是管程,而且1.5之后提供的SDK并发包,也是以管程技术为基础的。除此之外,C/C++、C#等高级语言也都支持管程。可以这么说,管程就是一把解决并发问题的万能钥匙。什么是管程不知道你是否曾思考过这个问题:为什么Java在1.5之前仅仅提供了synchronized关键字及wait()、notif.原创 2021-11-30 21:11:46 · 207 阅读 · 0 评论 -
07 _ 安全性、活跃性以及性能问题
通过前面六篇文章,我们开启了一个简单的并发旅程,相信现在你对并发编程需要注意的问题已经有了更深入的理解,这是一个很大的进步,正所谓只有发现问题,才能解决问题。但是前面六篇文章的知识点可能还是有点分散,所以是时候将其总结一下了。并发编程中我们需要注意的问题有很多,很庆幸前人已经帮我们总结过了,主要有三个方面,分别是:安全性问题、活跃性问题和性能问题。下面我就来一一介绍这些问题。安全性问题相信你一定听说过类似这样的描述:这个方法不是线程安全的,这个类不是线程安全的,等等。那什么是线程安全呢?其实本质上就是正确.原创 2021-11-30 21:11:15 · 166 阅读 · 0 评论 -
06 _ 用“等待-通知”机制优化循环等待
由上一篇文章你应该已经知道,在破坏占用且等待条件的时候,如果转出账本和转入账本不满足同时在文件架上这个条件,就用死循环的方式来循环等待,核心代码如下:// 一次性申请转出账户和转入账户,直到成功while(!actr.apply(this, target)) ;如果apply()操作耗时非常短,而且并发冲突量也不大时,这个方案还挺不错的,因为这种场景下,循环上几次或者几十次就能一次性获取转出账户和转入账户了。但是如果apply()操作耗时长,或者并发冲突量大的时候,循环等待这种方案就不适用了,因为.原创 2021-11-30 21:10:36 · 171 阅读 · 0 评论 -
05 _ 一不小心就死锁了,怎么办?
在上一篇文章中,我们用Account.class作为互斥锁,来解决银行业务里面的转账问题,虽然这个方案不存在并发问题,但是所有账户的转账操作都是串行的,例如账户A 转账户B、账户C 转账户D这两个转账操作现实世界里是可以并行的,但是在这个方案里却被串行化了,这样的话,性能太差。试想互联网支付盛行的当下,8亿网民每人每天一笔交易,每天就是8亿笔交易;每笔交易都对应着一次转账操作,8亿笔交易就是8亿次转账操作,也就是说平均到每秒就是近1万次转账操作,若所有的转账操作都串行,性能完全不能接受。那下面我们就尝试着.原创 2021-11-30 21:10:05 · 142 阅读 · 0 评论 -
04 _ 互斥锁(下):如何用一把锁保护多个资源?
在上一篇文章中,我们提到受保护资源和锁之间合理的关联关系应该是N:1的关系,也就是说可以用一把锁来保护多个资源,但是不能用多把锁来保护一个资源,并且结合文中示例,我们也重点强调了“不能用多把锁来保护一个资源”这个问题。而至于如何保护多个资源,我们今天就来聊聊。当我们要保护多个资源时,首先要区分这些资源是否存在关联关系。保护没有关联关系的多个资源在现实世界里,球场的座位和电影院的座位就是没有关联关系的,这种场景非常容易解决,那就是球赛有球赛的门票,电影院有电影院的门票,各自管理各自的。同样这对应到编程领域,.原创 2021-11-30 21:09:30 · 286 阅读 · 0 评论 -
03 _ 互斥锁(上):解决原子性问题
在第一篇文章中我们提到,一个或者多个操作在CPU执行的过程中不被中断的特性,称为“原子性”。理解这个特性有助于你分析并发编程Bug出现的原因,例如利用它可以分析出long型变量在32位机器上读写可能出现的诡异Bug,明明已经把变量成功写入内存,重新读出来却不是自己写入的。那原子性问题到底该如何解决呢?你已经知道,原子性问题的源头是线程切换,如果能够禁用线程切换那不就能解决这个问题了吗?而操作系统做线程切换是依赖CPU中断的,所以禁止CPU发生中断就能够禁止线程切换。在早期单核CPU时代,这个方案的确是可行.原创 2021-11-30 21:08:27 · 165 阅读 · 0 评论 -
02 _ Java内存模型:看Java如何解决可见性和有序性问题
上一期我们讲到在并发场景中,因可见性、原子性、有序性导致的问题常常会违背我们的直觉,从而成为并发编程的Bug之源。这三者在编程领域属于共性问题,所有的编程语言都会遇到,Java在诞生之初就支持多线程,自然也有针对这三者的技术方案,而且在编程语言领域处于领先地位。理解Java解决并发问题的解决方案,对于理解其他语言的解决方案有触类旁通的效果。那我们就先来聊聊如何解决其中的可见性和有序性导致的问题,这也就引出来了今天的主角——Java内存模型。Java内存模型这个概念,在职场的很多面试中都会考核到,是一个热门.原创 2021-11-29 00:06:57 · 156 阅读 · 0 评论 -
01 _ 可见性、原子性和有序性问题:并发编程Bug的源头
如果你细心观察的话,你会发现,不管是哪一门编程语言,并发类的知识都是在高级篇里。换句话说,这块知识点其实对于程序员来说,是比较进阶的知识。我自己这么多年学习过来,也确实觉得并发是比较难的,因为它会涉及到很多的底层知识,比如若你对操作系统相关的知识一无所知的话,那去理解一些原理就会费些力气。这是我们整个专栏的第一篇文章,我说这些话的意思是如果你在中间遇到自己没想通的问题,可以去查阅资料,也可以在评论区找我,以保证你能够跟上学习进度。你我都知道,编写正确的并发程序是一件极困难的事情,并发程序的Bug往往会诡异.原创 2021-11-29 00:06:07 · 160 阅读 · 0 评论