高并发编程必备基础

一、前言

借用Java并发编程实践中的话"编写正确的程序并不容易,而编写正常的并发程序就更难了",相比于顺序执行的情况,多线程的线程安全问题是微妙而且出乎意料的,因为在没有进行适当同步的情况下多线程中各个操作的顺序是不可预期的,本文算是对多线程情况下同步策略的一个一个简单介绍。

二、 什么是线程安全问题

线程安全问题是指当多个线程同时读写一个状态变量,并且没有任何同步措施时候,导致脏数据或者其他不可预见的结果的问题。Java中首要的同步策略是使用Synchronized关键字,它提供了可重入的独占锁。

三、 什么是共享变量可见性问题

要谈可见性首先需要介绍下多线程处理共享变量时候的Java中内存模型。

image.png

Java内存模型规定了所有的变量都存放在主内存中,当线程使用变量时候都是把主内存里面的变量拷贝到了自己的工作空间或者叫做工作内存。

image.png

如图是双核CPU系统架构,每核有自己的控制器和运算器,其中控制器包含一组寄存器和操作控制器,运算器执行算术逻辑运算,并且有自己的一级缓存,并且有些架构里面双核还有个共享的二级缓存。`
对应Java内存模型里面的工作内存,在实现上这里是指L1或者L2缓存或者自己cpu的寄存器 `

当线程操作一个共享变量时候操作流程为:

  • 线程首先从主内存拷贝共享变量到自己的工作内存
  • 然后对工作内存里的变量进行处理
  • 处理完后更新变量值到主内存

那么假如线程A和B同时去处理一个共享变量,会出现什么情况那?

首先他们都会去走上面的三个流程,假如线程A拷贝共享变量到了工作内存,并且已经对数据进行了更新但是还没有更新会主内存,这时候线程B拷贝共享变量到了自己的工内存进行处理,处理后,线程A才把自己的处理结果更更新到主内存,可知 线程B处理的并不是线程A处理后的结果,也就是说线程A处理后的变量值对线程B不可见,这就是共享变量的可见性问题。

原文链接