当前位置: 首页 > news >正文

Java保证线程安全的方式有哪些?

​ 一位工作5年的小伙伴面试时被问到这样一道题,说Java保证线程安全的方式有哪些?

今天,我给大家分享一下我的理解。

1、线程不安全的原因

回答这个问题之前,得先了解导致对象线程不安全的原因,主要有三个:

  1. 原子性:一个或者多个操作在CPU执行过程中被中断。
  2. 可见性:一个线程对象共享变量的修改,导致另一个线程不能立即看到。
  3. 有序性:程序执行的顺序没有按照代码的先后顺序执行。

原子性和可见性比较容易理解,重点分析一下有序性。为什么程序执行的顺序会和代码的编写顺序不一致呢?这就得理解Java平台的两种编译器,静态编译器javac和动态编译器jit(just in time)。

静态编译器是将.java文件编译成.class文件,JVM加载后就可以执行了。

而动态编译器是要将.class文件编译成机器码,再由JVM执行。有时候,动态编译器为了程序的整体性能会对指令进行重排序,但是,这又会导致源代码中指定的内存访问顺序和实际的执行顺序不一致,就会出现线程不安全的问题。

​2、如何保证线程安全

那么,针对以上三种情况,如何保证对象的线程安全呢?

第1个,针对原子性。

(1)JDK提供了非常多的Atomic类,比如AtomicInteger、AtomicLong、AtomicBoolean等等。这些类都是通过CAS来保证原子性。

(2)另外,Java还提供了各种锁机制,来保证锁内的代码块在同一时刻只能被一个线程执行。比如用synchronized加锁。这样,就可以保证一个线程对资源进行读、写操作时,其他线程不可以对这个资源进行操作,从而保证了线程安全。 ​

第2个,针对可见性。

同样可以使用synchronized关键字加锁来解决。与此同时,Java提供了volatile关键字。它要优于synchronized的性能,同样也可以保证修改后对其他线程可见。volatile一般用于对变量的写操作,不依赖于当前值的场景中,比如状态标记量等等。

第3个,针对有序性。

也可以使用synchronized关键字定义同步代码块,或者同步方法来保证有序性。另外也可以通过Lock接口来保证有序性。

以上就是对Java保证线程安全的思路。当然,保证对象线程安全的方式还有很多,比如还可以使用ThreadLocal实现多个线程之间的数据隔离,使用final关键字等等,我这里就不一一列举了。最后,我留一个思考题,单用volatile关键字,能保证线程安全吗?

相关文章:

  • 《数据结构》队列及其经典面试题
  • 计算机图形学(十一):真实感图形(光照模型、材质模型)
  • 【云原生】Hadoop HA on k8s 环境部署
  • 四元数是什么
  • 大衣哥家里再添喜事,生产厂家免费送给他一辆新车
  • 爬取疫情数据并存到mysql数据库
  • 场景应用:网络的子网掩码为255.255.240.0,它能够处理的主机数是多少?
  • Qt5开发从入门到精通——第七篇六节( 图形视图—— 图元的旋转、缩放、切变、和位移)
  • 内网穿透工具natapp的注册、下载、安装与使用(详细教程)
  • CDH openssl 安装报错 TXT_DB error number 2
  • 【Linux线程同步专题】一、什么是线程同步、互斥量与死锁
  • 内网渗透-Linux权限维持
  • Git 便捷操作
  • 美国项目管理协会和埃森哲最新报告:越来越多的公司设立首席转型官一职
  • y145.第八章 Servless和Knative从入门到精通 -- 消息系统基础和Eventing及实践(九)
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Android交互
  • express如何解决request entity too large问题
  • iOS 系统授权开发
  • Median of Two Sorted Arrays
  • mysql 数据库四种事务隔离级别
  • session共享问题解决方案
  • ubuntu 下nginx安装 并支持https协议
  • vue总结
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 对JS继承的一点思考
  • 前端js -- this指向总结。
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 一份游戏开发学习路线
  • 由插件封装引出的一丢丢思考
  • 智能合约开发环境搭建及Hello World合约
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #前后端分离# 头条发布系统
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (LeetCode C++)盛最多水的容器
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (分布式缓存)Redis分片集群
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (转)http协议
  • *Django中的Ajax 纯js的书写样式1
  • ./configure,make,make install的作用
  • .jks文件(JAVA KeyStore)
  • .NET Core 版本不支持的问题
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • .NET中的十进制浮点类型,徐汇区网站设计
  • @Autowired多个相同类型bean装配问题
  • @GetMapping和@RequestMapping的区别
  • @javax.ws.rs Webservice注解
  • [ vulhub漏洞复现篇 ] Hadoop-yarn-RPC 未授权访问漏洞复现
  • [16/N]论得趣