问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

7个连环问题揭开java多线程背后的核心原理!

发布网友 发布时间:2024-09-25 22:05

我来回答

1个回答

热心网友 时间:2024-10-06 03:58

摘要:很多java入门新人一想到java多线程, 就会觉得很晕很绕,什么可见不可见的,也不了解为什么sync怎么就锁住了代码。

很多java入门新人一想到java多线程, 就会觉得很晕很绕,什么可见不可见的,也不了解为什么sync怎么就锁住了代码。

因此我在这里会提多个问题,如果能很好地回答这些问题,那么算是你对java多线程的原理有了一些了解,也可以借此学习一下这背后的核心原理。

Q: java中的主内存和工作内存是指什么?

A:java中, 主内存中的对象引用会被拷贝到各线程的工作内存中, 同时线程对变量的修改也会反馈到主内存中。

主内存对应于java堆中的对象实例部分(物理硬件的内存)

工作内存对应于虚拟机栈中的部分区域( 寄存器,高速缓存)

工作内存中是拷贝的工作副本

拷贝副本时,不会吧整个超级大的对象拷贝过来, 可能只是其中的某个基本数据类型或者引用。

因此我们知道各线程使用内存数据时,其实是有主内存和工作内存之分的。并不是一定每次都从同一个内存里取数据。

或者理解为大家使用数据时之间有一个缓存。

Q: 多线程不可见问题的原因是什么?

A:这里先讲一下虚拟机定义的内存原子操作:

lock: 用于主内存, 把变量标识为一条线程独占的状态

unlock : 主内存, 把锁定状态的变量释放

read: 读取, 从主内存读到工作线程中

load: 把read后的值放入到 工作副本中

use: 使用工作内存变量, 传给工作引擎

assign赋值: 把工作引擎的值传给工作内存变量

store: 工作内存中的变量传到主内存

write: 把值写入到主内存的变量中

根据这些指令,看一下面这个图, 然后再看图片之后的流程解释,就好理解了。

read和load、store、write是按顺序执行的, 但是中间可插入其他的操作。不可单独出现。

assgin之后, 会同步后主内存。即只有发生过assgin,才会做工作内存同步到主内存的操作。

新变量只能在主内存中产生

工作内存中使用某个变量副本时,必须先经历过assign或者load操作。 不可read后马上就use

lock操作可以被同一个线程执行多次,但相应地解锁也需要多次。

执行lock时,会清空工作内存中该变量的值。 清空后如果要使用,必须重新做load或者assign操作

unlock时,需要先把数据同步回主内存,再释放。

因此多线程普通变量的读取和写入操作存在并发问题, 主要在于2点:

只有assgin时, 才会更新主内存, 但由于指令重排序的情况,导致有时候某个assine指令先执行,然后这个提前被改变的变量就被其他线程拿走了,以至于其他线程无法及时看到更新后的内存值。

assgin时从工作内存到主内存之间,可能存在延迟,同样会导致数据被提前取走存到工作线程中。

Q: 那么volatile关键字为什么就可以实现可见性?可见性就是并发修改某个值后,这个值的修改对其他线程是马上可见的。

A: java内存模型堆volatile定义了以下特殊规则:

当一个线程修改了该变量的值时,会先lock住主存, 再立刻把新数据同步回内存。

使用该值时,其他工作内存都要从主内存中刷新!

这个期间会禁止对于该变量的指令重排序

禁止指令重排序的原理是在给volatile变量赋值时,会加1个lock动作, 而前面规定的内存模型原理中, lock之后才能做load或者assine,因此形成了1个内存屏障。

Q: 上面提到lock后会限制各工作内存要刷新主存的值load进来后才能用, 这个在底层是怎么实现的?

A:利用了cpu的总线锁+ 缓存一致性+ 嗅探机制实现, 属于计算机组成原理部分的知识。

这也就是为什么violate变量不能设置太多,如果设置太多,可能会引发总线风暴,造成cpu嗅探的成本大大增加。

Q: 那给方法加上synchronized关键字的原理是什么?和volatie的区别是啥?

A:

synchronized的重量级锁是通过对象内部的监视器(monitor)实现

monitor的线程互斥就是通过操作系统的mutex互斥锁实现的,而操作系统实现线程之间的切换需要从用户态到内核态的切换,所以切换成本非常高。

每个对象都持有一个moniter对象

具体流程如下:

首先,class文件的方法表结构中有个访问标志access_flags, 设置ACC_SYNCHRONIZED标志来表示被设置过synchronized。

线程在执行方法前先判断access_flags是否标记ACC_SYNCHRONIZED,如果标记则在执行方法前先去获取monitor对象。

获取成功则执行方法代码且执行完毕后释放monitor对象

如果获取失败则表示monitor对象被其他线程获取从而阻塞当前线程

注意,如果是sync{}代码块,则是通过在代码中添加monitorEnter和monitorExit指令来实现获取和退出操作的。

如果对C语言有了解的,可以看看这个大哥些的文章Java精通并发-通过openjdk源码分析ObjectMonitor底层实现

Q: synchronized每次加锁解锁需要切换内核态和用户态, jvm是否有对这个过程做过一些优化?

A:jdk1.6之后, 引入了锁升级的概念,而这个锁升级就是针对sync关键字的

锁的状态总共有四种,级别由低到高依次为:无锁、偏向锁、轻量级锁、重量级锁

四种状态会随着竞争的情况逐渐升级,而且是不可逆的过程,只能进行锁升级(从低级别到高级别),不能锁降级(高级别到低级别)

因此sync关键字不是一开始就直接使用很耗时的同步。而是一步步按照情况做升级

当对象刚建立,不存在锁竞争的时候, 每次进入同步方法/代码块会直接使用偏向锁

偏向锁原理: 每次尝试在对象头里设置当前使用这个对象的线程id, 只做一次,如果成功了就设置好threadId, 只要没有出现新的thread访问且markWord被修改,那么久)

2. 当发现对象头的线程id要被修改时,说明存在竞争时。升级为轻量级锁

轻量级锁采用的是自旋锁,如果同步方法/代码块执行时间很短的话,采用轻量级锁虽然会占用cpu资源但是相对比使用重量级锁还是更高效的。 CAS的对象是对象头的Mark Word, 此时仍然不会去调系统底层的方法做阻塞。

3. 但是如果同步方法/代码块执行时间很长,那么使用轻量级锁自旋带来的性能消耗就比使用重量级锁更严重,这时候就会升级为重量级锁,也就是上面那个问题中提到的操作。

Q: 锁只可以升级不可以降级, 确定是都不能降级吗?

A:有可能被降级, 不可能存在共享资源竞争的锁。java存在一个运行期优化的功能需要开启server模式外加+DoEscapeAnalysis表示开启逃逸分析。

如果运行过程中检测到共享变量确定不会逃逸,则直接在编译层面去掉锁

举例:StringBuffer.append().append()

例如如果发现stringBuffer不会逃逸,则就会去掉这里append所携带的同步

而这种情况肯定只能发生在偏向锁上, 所以偏向锁可以被重置为无锁状态。

本文分享自华为云社区,作者:breakDraw。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
怎样让孩子主动找老师补课? 表格列求和公式怎么设置 求和函数公式怎么输入 北京注册成立一个公司需要多少钱 北京公司都是什么 手机导航地图语音怎么下载 如何分别真金和仿金首饰 怎样区分真金和仿金首饰呢 小学生新年晚会主持人的串词!!(不要太多)急 大大后天就需要了!!!_百度... 周年晚会策划公司 奥格瑞玛传送门大厅在哪 Java 锁详解 【Java基础知识 17】聊一聊同步代码块 第二个字是群的成语有哪些 最近电手机总是被一些莫名其妙的电话号码打进来求大神帮助 热血江湖SF强7 8 9方法 总是被人电话骚扰,我很受精神刺激,我该如何是好?求大神帮助_百度... 热血江湖私服怎样练级? 有人打电话骚扰,求帮忙! 热血江湖私服血有时候卡血几万是怎么回事? 求各位大神帮忙。最近被一网友骚扰,他知道我的手机号,用不同的号码给... 我电话不知道被谁留这上面了。每天骚扰电话特别多。求大神解救。用什么... 热血江湖SF怎么卡血 热血江湖SF卡血 铁锈怎么造句 团的工作有哪些 如何凝聚青春力量 为什么附近的人看不到我的位置信息? 同一个手机登录两个微信号其中一个正常使用,另一个是新号码,但是上附近... 为什么我这个新申请的微信号换了两个手机,在附近人里别人看不到我呢 合理使用家电 保护宝宝健康 Java多线程:从基本概念到避坑指南 国庆节为什么学校要补课? 河蚌的贝壳上有一圈一圈的纹路,这些纹路是由外套膜形成的还是有外套膜... 自动挡和手动挡的含义 兔子吃食有节制吗?可不可以给他喂水。 民警为什么不配枪 民警配枪可以自选吗 民警身中七刀为什么不配枪 鸡精和味精到底哪个更健康?可能很多人都吃错了,现在知道也不晚_百度知... 人工呼吸的正确方法是呼还是吸 成人心肺复苏人工呼吸的操作步骤 心肺复苏人工呼吸的正确步骤 人工呼吸的要点有哪些内容 苹果怎么设置微信来电屏幕显示 ...时却会变成无声状态,无来电响铃和震动,只看到屏幕上有来电显示... 中国的官厅会计是什么 请教,长1.5米的鱼缸,宽500,高700,养了一条半米的银龙,需要24小时给氧吗... 省考考完后一般多久出成绩 省考笔试成绩多久出来 一般考完省考多长时间出成绩啊