Java并发编程理论入门理解笔记

本文介绍了Java并发编程中常见的问题,如可见性、原子性和有序性,以及如何通过Java内存模型、volatile关键字和锁机制来解决这些问题。同时,讨论了死锁的避免策略和等待-通知机制的应用,强调了并发编程中应注意的安全性、活跃性和性能问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java并发编程理论入门理解笔记

参考材料:极客时间《Java并发编程实战》–王宝令

并发编程Bug的源头

你我都知道,编写正确的并发程序是一件非常困难的事情,并发程序的Bug往往会诡异的出现,然后又诡异的消失。为了能够轻松并精准地解决并发编程中的Bug,了解这些Bug出现的源头是必须的。

计算机中有很主要的三个部分:CPU、内存和I/O设备,我们清楚的知道,其三者之间是存在速度的差异的。为了合理的利用CPU的高性能,平衡这三者的速度差异,计算机系统结构、操作系统以及编译程序都做出了方案去进行优化,使得我们的程序可以更加高效率地运行,但同时也会带来相应的问题。(这里我们就不得不提一件事情,任何的解决方案在解决当前问题的同时,也往往会引起其他的问题,所以在采用一项技术的同时,一定要清楚它带来的问题是什么,以及如何规避)

在计算机系统结构中,我们引入了缓存,用于均衡内存和CPU之间的速度差异。但是在这个多核的时代,每一个CPU中都有自己的缓存,这个时候,CPU缓存与内存的数据一致性就没有那么容易保持了,简单来说就是两个CPU之间对各自的缓存中的变量进行的操作对另一个CPU是不可见的,这就带来的可见性的问题(一个线程对共享变量的修改,另外一个线程能够立刻看到,我们称为可见性)。

在操作系统中,我们增加了进程、线程,以分时复用CPU,进而均衡CPUI/O设备的速度差异。操作系统允许某一个进程先执行一小段时间,然后待过了一段时间之后,操作系统会重新选择一个进程来执行,这个一段时间,我们就称为时间片。Java并发程序是基于多线程的,这自然也会涉及到任务切换。因为CPU能保证的原子操作是CPU指令级别的,而不是高级语言的操作符,这就导致在Java并发编程的过程中出现原子性的问题(我们把一个或者多个操作在CPU执行的过程中不被中断的特性称为原子性)。

在编译程序中,我们会优化指令的执行次序,使得缓存能够得到更加合理的利用。但是由于编译程序对原有的语句的执行顺序进行了改变,在某些情况下会影响到程序的最终结果。这就是编译程序带来的有序性问题(有序性即程序执行的顺序按照代码的先后顺序执行)。

在这里我们以及清楚的了解了到了并发编程Bug的主要的源头:可见性、原子性和有序性。只要我们能够深刻理解可见性、原子性、有序性在并发场景下的原理,很多并发Bug都是可以理解、可以诊断的。那么我们该如何去解决这三个问题呢?

Java内存模型

Java内存模型(Java Memory ModelJMM)用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。站在一个程序员的角度上进行理解,Java内存模型规范了JVM如何提供按需禁用缓存和编译优化的方法。具体来说,这些方法包括volatilesynchronizedfinal三个关键字,以及Happens-Before规则。所以说Java内存模型为我们解决可见性和有序性问题提供了帮助。

volatile关键字其实并非是Java语言特有的,在C语言里也有,它最原始的意义就是禁用CPU缓存。如果我们将一个变量使用volatile修饰,这就指示 编译器,这个变量是共享且不稳定的,每次使用它都到主存中进行读取。

volatile语义增强是离不开Happens-Before规则,所谓Happens-Before规则要表达的是:前面一个操作的结果对后续操作是可见的。这里只说明以下的六项规则:

  1. 程序次序规则:在一个线程内,按照控制流顺序,书写在前面的操作Happens-Before于书写在后面的操作。

  2. 管程锁定规则:一个unlock操作Happens-Before于后面对一个锁的lock操作。

  3. volatile变量规则:对一个volatile变量的写操作Happens-Before于后面对这个变量的读操作。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值