gball个人知识库
首页
基础组件
基础知识
算法&设计模式
  • 操作手册
  • 数据库
  • 极客时间
  • 每日随笔
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 画图工具 (opens new window)
关于
  • 网盘 (opens new window)
  • 分类
  • 标签
  • 归档
项目
GitHub (opens new window)

ggball

后端界的小学生
首页
基础组件
基础知识
算法&设计模式
  • 操作手册
  • 数据库
  • 极客时间
  • 每日随笔
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 画图工具 (opens new window)
关于
  • 网盘 (opens new window)
  • 分类
  • 标签
  • 归档
项目
GitHub (opens new window)
  • 面试

  • 数据库

  • linux

  • node

  • tensorFlow

  • 基础组件

  • 基础知识

    • java集合

    • jvm调优

    • java并发编程

      • 进程与线程
      • 多线程的方法介绍与使用
      • 线程死锁
      • 守护线程与用户线程
      • ThreadLocal了解
      • 什么是多线程并发编程
        • 了解什么是并发,什么是并行?
        • 内存可见性问题
        • 解决内存可见性的方法
          • synchronized 关键字
          • volatile 关键字
      • unsafe类了解
      • 伪共享
      • 锁的了解
      • ThreadLocalRandom原理解析
      • LongAdder,LongAccumulator类了解
      • 实践-创建多少线程合适
      • 线程通信——通知与等待
      • 缓存一致性问题
      • 利用Excutors异步执行任务
      • 线程池
      • 线程池操作数据库造成死锁
      • Java 浅拷贝和深拷贝的理解和实现方式
      • java内存模型JMM
      • 锁升级过程
      • io模型
      • 关键字介绍
      • AQS解析
    • java网络编程

    • java8新特性

    • javaAgent

    • java高级

  • 算法与设计模式

  • 分布式

  • 疑难杂症

  • go学习之旅

  • 极客时间

  • 知识库
  • 基础知识
  • java并发编程
ggball
2022-04-27

什么是多线程并发编程

# 什么是多线程并发编程

# 了解什么是并发,什么是并行?

并发:一段时间内,执行多个没有结束的任务。 并行:单位时间内,同时执行多个任务。

注意:并发任务强调在一个时间段内同时执行,而一个时间段由多个单位时间累积而成,所以说并发的多个任务在单位时间内不一定同时在执行

而在多线程编程实践中,线程的个数往往多于CPU的个数,所以一般都称多线程并发编程而不是多线程并行编程。

# 内存可见性问题

首先看下java的内存模型,可以更好了解问题 20220427161926 每个线程都有自己的工作内存和缓存(一级缓存),主内存保存存着共享变量,CPU还提供一个共享的二级缓存,如果二级缓存有对应数据,线程会优先取二级缓存获取或刷入

接下来说一个例子,演示为什么会有内存可见性的问题

20220427175020


假设现在有一个双核cpu服务器,首先thread1 获取x的值,这时候只有共享的主内存有值,二级缓存和thread1的私有内存和一级缓存都没有x的值,因此thread1会直接去主内存获取值。 20220427175118


thread1会直接从主内存,将x=0写入两级缓存,写入私有内存,然后再将x的值修改为1,最后再将x=1刷到两级缓存,和主内存中。

20220427175237


这时候来了个thread2,也准备修改x的值,开始时它的私有内存和一级缓存也是空的,但是主内存和二级缓存的x值为1,所以thread2会优先获取二级缓存中的值

20220427175314


thread2获取二级缓存x=1,写入自己的一级缓存和私有内存,然后将x修改为2,私有内存和一级缓存都修改为2,x=2也刷入二级缓存和主内存,到这里都没有问题。

20220427175425


这时thread1又想将x的值修改为3,thread1看自己的一级缓存有x的值,就不会去二级缓存获取,这样就造成了读取的数据和主内存上的不一致

# 解决内存可见性的方法

# synchronized 关键字

# synchronized关键字介绍

Synchronized关键字是Java中用于实现线程同步的重要特性之一。它可以应用于方法或代码块,用于确保在多线程环境下对共享资源的安全访问。

  • 修饰静态代码块
  • 修饰属性变量
  • 修饰属性方法

使用synchronized关键字,当线程拿到类或对象的监视器锁,会具有排他性,就是其他线程不能抢占该资源,直到线程释放锁(释放锁的时机有正常执行完和被打断)

# synchronized内存语义

当被synchronized修饰的方法被执行时: 线程进入方法,线程读取的变量会从工作内存清除,从而去读取主内存的变量值 线程退出方法,会将线程修改的值刷回到主内存

# volatile 关键字

被volatile修饰的变量,被读取时不会去工作内存读取,而是直接去主内存读取,写入变量值时,将工作内存的变量值写回主内存。 可以防止指令重排。

原子性,可见性,有序性 是如何实现的

上次更新: 2025/06/29, 17:11:31
ThreadLocal了解
unsafe类了解

← ThreadLocal了解 unsafe类了解→

最近更新
01
AIIDE
03-07
02
githubActionCICD实战
03-07
03
windows安装Deep-Live-Cam教程
08-11
更多文章>
Theme by Vdoing
总访问量 次 | 总访客数 人
| Copyright © 2021-2025 ggball | 赣ICP备2021008769号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×

评论

  • 评论 ssss
  • 回复
  • 评论 ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
  • 回复
  • 评论 ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
  • 回复
×