红茶的个人站点

  • 首页
  • 专栏
  • 开发工具
  • 其它
  • 隐私政策
Awalon
Talk is cheap,show me the code.
  1. 首页
  2. 其它
  3. 正文

什么是线程安全?

2023年9月10日 1005点热度 0人点赞 0条评论

前段时间有个面试,面试官问我 Spring 中的 Bean 是不是线程安全的,当时有点懵逼,主要是觉得线程安全和是不是 Spring 的 Bean 没关系,脑子一下没转过弯,所以回答了一些不着边际的问题。刚下楼溜了一圈,正好回想到这个问题,试着重新回答一下。

要回答什么是线程安全,那就必须聊一下什么是线程不安全。

个人觉得线程不安全要满足以下几个条件:

  • 多线程,这个是肯定的,单线程有个屁的线程安全问题。

  • 多个线程之间有共享资源,换句话说有任务需要它们协同完成。这点是最重要的,多线程编程正是为了利用多核并行的能力提升解决问题的效率,但协同工作带来的线程安全问题也随之而来。

  • 共享资源有写操作,将共享资源改为只读是解决线程安全问题的一种思路。

  • 写操作不是原子性,即使是最简单的一行 Java 代码,翻译成汇编也可能是多条,所以一般而言大多数单行代码都不是原子性的。但也有一些基础类型的操作是原子性的,但是这需要高超的汇编技巧,此外这么做并没有什么好处,而且极度依赖于特定平台,很可能换一台机器运行代码就会翻译成多条汇编,变成线程不安全的。

  • 写操作不是独占的,这也是最基础的解决线程安全的思路,即在执行写操作时给资源加锁,阻止其它线程对该资源的读写,修改完资源后再去除锁。

好了,个人觉得以上就是线程安全问题的全部了,如果满足了上边所有条件,那就是线程不安全的,反之,就是线程安全的。

至于 Spring Bean,依然遵循上边的规则,并没有什么特殊情况。只不过在基于 Spring 的 Web 开发中,绝大多数我们打交道的 Spring Bean 都是单例(比如各种 Controller),这些单例会被大量并发的 HTTP 请求复用,也就是说基本满足上边说的第一条和第二条。不过这些单例使用的数据来源基本是 Redis 或者数据库,再就是 MQ 之流。显然这些成熟的中间件无一不是为了应对大规模的并发请求而生的,所以必然都是线程安全的。所以一般来说这些 Spring Bean 是线程安全的。但是,如果你添加了一个线程不安全的成员变量,且存在共享的非独占写操作,就可能满足上边所说的所有条件,那就会变成线程不安全。

可能我说的有点绕,不过意思就是如此,总之,Spring Bean 在这方面并无特殊之处。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2023年9月10日

魔芋红茶

加一点PHP,加一点Go,加一点Python......

点赞
< 上一篇
下一篇 >

文章评论

取消回复

*

code

COPYRIGHT © 2021 icexmoon.cn. ALL RIGHTS RESERVED.
本网站由提供CDN加速/云存储服务

Theme Kratos Made By Seaton Jiang

宁ICP备2021001508号

宁公网安备64040202000141号