千家信息网

Java并发面试题实例分析

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要讲解了"Java并发面试题实例分析",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java并发面试题实例分析"吧!题目结论多线程并发的同时进
千家信息网最后更新 2026年11月03日Java并发面试题实例分析

这篇文章主要讲解了"Java并发面试题实例分析",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java并发面试题实例分析"吧!

题目

结论

多线程并发的同时进行set、get操作, A线程调用set方法,B线程并一定能对这个改变可见!!!

分析

这个类非常简单,里面有一个属性,有2个方法:get、set方法,一个用来设置属性值,一个用来获取属性值,在设置属性方法上面加了synchronized。

隐式信息:多线程并发的同时进行set、get操作, A线程调用set方法,B线程可以里面感知到吗???

说到这里, 问题就变成了synchronized在刚刚说的上下文下面能否保证可见性!!!

关键词synchronized的用法

指定加锁对象:对给定对象加锁,进入同步代码前需要获得给定对象的锁。

直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。

直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。

synchronized它的工作就是对需要同步的代码加锁,使得每一次只有一个线程可以进入同步块(其实是一种悲观策略)从而保证线程之间得安全性。

从这里我们可以知道,我们需要分析的属于第二类情况,也就是说多个线程如果同时进行set方法的时候,由于存在锁,所以会一个一个进行set操作,并且是线程安全的,但是get方法并没有加锁,表示假如A线程在进行set的同时B线程可以进行get操作。并且可以多个线程同时进行get操作,但是同一时间最多只能有一个set操作。

Java 内存模型 happens-before原则

JSR-133 内存模型使用 happens-before 的概念来阐述操作之间的内存可见性。在 JMM 中,如果 一个操作执行的结果需要对另一个操作可见 ,那么这两个操作之间必须要存在 happens-before 关系。这里提到的两个操作既可以是在一个线程之内,也可以是在不同线程之间。

与程序员密切相关的 happens-before 规则如下:

程序顺序规则:一个线程中的每个操作,happens-before 于该线程中的任意后续操作。

监视器锁规则:对一个监视器的解锁,happens-before 于随后对这个监视器的加锁。

volatile 变量规则:对一个 volatile 域的写,happens-before 于任意后续对这个 volatile 域的读。

传递性:如果 A happens-before B,且 B happens-before C,那么 A happens-before C。

注意,两个操作之间具有 happens-before 关系,并不意味着前一个操作必须要在后一个操作之前执行!happens-before 仅仅要求前一个操作(执行的结果)对后一个操作可见,且前一个操作按顺序排在第二个操作之前(the first is visible to and ordered before the second)。

其中有 监视器锁规则:对一个监视器的解锁,happens-before 于随后对这个监视器的加锁。这一条,仅仅只是针对synchronized的set方法,而对于get并没有这方面的说明。

其实在这种上下文下面一个synchronized的set方法,一个普通的get方法,a线程调用set方法,b线程并一定能对这个改变可见!

volatile

volatile可见性

前面happens-before原则就提到: volatile 变量规则:对一个 volatile 域的写,happens-before 于任意后续对这个 volatile 域的读。 volatile从而保证了多线程下的可见性!!!

volatile 禁止内存重排序

下面是 JMM 针对编译器制定的 volatile 重排序规则表:


为了实现 volatile 的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。

下面是基于保守策略的 JMM 内存屏障插入策略:

在每个 volatile 写操作的前面插入一个 StoreStore 屏障。

在每个 volatile 写操作的后面插入一个 StoreLoad 屏障。

在每个 volatile 读操作的后面插入一个 LoadLoad 屏障。

在每个 volatile 读操作的后面插入一个 LoadStore 屏障。

下面是保守策略下,volatile 写操作 插入内存屏障后生成的指令序列示意图:


下面是在保守策略下,volatile 读操作 插入内存屏障后生成的指令序列示意图:


上述 volatile 写操作和 volatile 读操作的内存屏障插入策略非常保守。在实际执行时,只要不改变 volatile 写-读的内存语义,编译器可以根据具体情况省略不必要的屏障。

模拟

通过上面的分析,其实这个题目涉及到的内容都提到了,并且进行了解答。

虽然你知道的原因,但是想模拟并不是一件容易的事情!,下面我们来模拟看看效果:

publicclassThreadSafeCache{intresult;publicintgetResult(){returnresult; }publicsynchronizedvoidsetResult(intresult){this.result = result; }publicstaticvoidmain(String[] args){ ThreadSafeCache threadSafeCache =newThreadSafeCache();for(inti =0; i <8; i++) {newThread(() -> {intx =0;while(threadSafeCache.getResult() <100) { x++; } System.out.println(x); }).start(); }try{ Thread.sleep(1000); }catch(InterruptedException e) { e.printStackTrace(); } threadSafeCache.setResult(200); }}

效果:


程序会一直卡在这边不动,表示set修改的200,get方法并不可见!!!

添加volatile 关键词观察效果

其实例子中synchronized关键字可以去掉,仅仅用volatile即可。


效果:


代码很快正常结束了!

感谢各位的阅读,以上就是"Java并发面试题实例分析"的内容了,经过本文的学习后,相信大家对Java并发面试题实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

线程 方法 内存 屏障 实例 分析 规则 监视器 策略 监视 之间 代码 同时 同步 发面 实例分析 试题 属性 效果 两个 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广东猪兼强互联网科技有限公司 互联网的科技创新 互联网科技股有哪些 深圳前海聚择互联网科技有限公司 剑昆互联网络科技有限公司临桂 上海宁丞科技互联网 武汉健翔互联网络科技有限公司 和信科技工业互联网 晋城互联网科技 玉溪新华互联网科技好不好 互联网时代的科技公司 合肥互联网科技公司公章图片 互联网金融科技公司的优势 领航科技大厦互联网公司 有人说阿里系是互联网科技企业 35岁以上互联网科技行业 上海乐五互联网科技有限公司 云南互联网科技学费 承德科技产业互联网平台 伍佰万互联网科技是干嘛的 喔噻互联网科技有限公司 科技与互联网发展 美国互联网黑科技 上海万想互联网科技 互联网科技生活的内容 哈尔滨新华互联网科技学院 21世纪互联网科技成就 互联网科技平台产品运营 科技互联网公司两年变化 宁波允成互联网科技有限公司
0