「Java面试」将线程安全讲的如此清新脱俗:你对线程安全性的理解

简介: 一位4年工作经验的小伙伴,被问到一个非常抽象的问题,说,谈谈你对线程安全性的理解。如果平时只是刷刷面试题的话,遇到这种问题可能不知道如何说起了,往往需要自己组织语言。另外,如果平时积累不够的话,也很难说出一些自己独特的见解来。

一位4年工作经验的小伙伴,被问到一个非常抽象的问题,说,谈谈你对线程安全性的理解。如果平时只是刷刷面试题的话,遇到这种问题可能不知道如何说起了,往往需要自己组织语言。另外,如果平时积累不够的话,也很难说出一些自己独特的见解来。

今天,我分享一下我对线程安全的理解,希望能给小伙伴们作为参考。

另外,我花了1个多星期,准备了一份500页的PDF面试题解析配套文档,想获取的小伙伴可以扫描文章底部二维码领取!

(附赠10万字大厂内部面试资料!)

1、官方定义

线程安全通常是相对于多线程或者并发的情况下而言的。如果是单线程操作的话,就无所谓线程安全了。

edb3f17e2395f2c82ca95116724bb18d.jpg

简单来说,就是在多个线程环境下,访问同一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,在不做任何干预的强可选,调用这个对象的行为都可以获得预期的结果,那么这个对象就是线程安全的。

看完这段,是不是还是很难理解?下面,我来分享一下看我是如何理解的。

2、Tom的理解

96b6432f937e7699bad871eda6adc13d.jpg

我认为,在多线程环境下保证线程安全,无非就是保证对对象访问的原子性、有序性和多个线程之间的可见性。

10d3ae74f81f29346ef559eb0f6c43a0.jpg

原子性呢,说的是当一个线程执行一系列程序指令操作的时候,它应该是不可中断的,因为一旦出现中断,站在多线程的视角来看,这一系列的程序指令会出现前后执行结果不一致的问题。

这个和数据库里面的原子性是一样的,简单来说就是一段程序只能由一个线程完整的执行完成,而不能存在多个线程干扰。CPU的上下文切换 , 是导致出现多线程原子性问题的核心原因 , 而JDK面也提供了synchronized 关键字来解决原子性问题。

然后,就是可见性,相当于在多线程环境下,可能会存在读和写是发生在不同的线程里面,有可能出现某个线程对共享变量的修改,对其他线程不是实时可见的。导致可见性问题的原因有很多,比如 CPU的高速缓存、CPU的指令重排、编译器的指令重排等因素。

最后,就是有序性,指的是程序编写的指令顺序和最终 CPU 运行的指令顺序可能出现不一致的现象,这种现象也可以称为指令重排序,所以有序性也会导致可见性问题。可见性和有序性可以通过JDK提供的volatile 关键字来解决。

我认为,导致有序性、原子性、可见性问题的本质,是计算机设计的时候,为了最大化提升 CPU 利用率导致的。比如CPU设计了三级缓存、设计了 StoreBuffer、设计了缓存行这种预读机制、在操作系统里面,设计了线程模型、在编译器里面,设计了编译器的深度优化机制等等。

我们都在说,面试造火箭,工作拧螺丝。对于企业来说,如果选择一个对计算机底层原理了解更透彻的程序员,不用担心他滥用线程导致一些不可预测的安全问题。其实也是在降低用人成本。

最后,我把之前分享的视频全部整理成了文字,想获取的小伙伴可以扫描文章底部二维码拿!希望能够以此来提高各位粉丝的通过率。


image.gif


我是被编程耽误的文艺Tom,只弹干货不掺水!你们的支持就是我最大的动力!关注我,面试不再难!

相关文章
|
2天前
|
监控 Kubernetes Java
阿里面试:5000qps访问一个500ms的接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?
本文由40岁老架构师尼恩撰写,针对一线互联网企业的高频面试题“如何确定系统的最佳线程数”进行系统化梳理。文章详细介绍了线程池设计的三个核心步骤:理论预估、压测验证和监控调整,并结合实际案例(5000qps、500ms响应时间、4核8G机器)给出具体参数设置建议。此外,还提供了《尼恩Java面试宝典PDF》等资源,帮助读者提升技术能力,顺利通过大厂面试。关注【技术自由圈】公众号,回复“领电子书”获取更多学习资料。
|
7天前
|
安全 Java 程序员
面试直击:并发编程三要素+线程安全全攻略!
并发编程三要素为原子性、可见性和有序性,确保多线程操作的一致性和安全性。Java 中通过 `synchronized`、`Lock`、`volatile`、原子类和线程安全集合等机制保障线程安全。掌握这些概念和工具,能有效解决并发问题,编写高效稳定的多线程程序。
48 11
|
6天前
|
Java Linux 调度
硬核揭秘:线程与进程的底层原理,面试高分必备!
嘿,大家好!我是小米,29岁的技术爱好者。今天来聊聊线程和进程的区别。进程是操作系统中运行的程序实例,有独立内存空间;线程是进程内的最小执行单元,共享内存。创建进程开销大但更安全,线程轻量高效但易引发数据竞争。面试时可强调:进程是资源分配单位,线程是CPU调度单位。根据不同场景选择合适的并发模型,如高并发用线程池。希望这篇文章能帮你更好地理解并回答面试中的相关问题,祝你早日拿下心仪的offer!
25 6
|
11天前
|
监控 Dubbo Java
Java Dubbo 面试题
Java Dubbo相关基础面试题
|
11天前
|
SQL Java 数据库连接
Java MyBatis 面试题
Java MyBatis相关基础面试题
|
11天前
|
存储 监控 算法
Java JVM 面试题
Java JVM(虚拟机)相关基础面试题
|
11天前
|
SQL 监控 druid
Java Druid 面试题
Java Druid 连接池相关基础面试题
|
11天前
|
缓存 安全 算法
Java 多线程 面试题
Java 多线程 相关基础面试题
|
28天前
|
NoSQL Redis
单线程传奇Redis,为何引入多线程?
Redis 4.0 引入多线程支持,主要用于后台对象删除、处理阻塞命令和网络 I/O 等操作,以提高并发性和性能。尽管如此,Redis 仍保留单线程执行模型处理客户端请求,确保高效性和简单性。多线程仅用于优化后台任务,如异步删除过期对象和分担读写操作,从而提升整体性能。
61 1
|
3月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
71 1

热门文章

最新文章