一、根本原因

「CPU、内存、磁盘之间的速度差异」

  • 为了能同时执行多个任务,CPU 发展出时间片轮转、多核等
  • CPU 要从内存中读数据太慢了,所以给自己设置了缓存
  • CPU 读磁盘更慢了,所以可以让该线程阻塞

二、直接原因

缓存导致的可见性问题

CPU 把要处理的数据加载到自己的缓存中,处理完了放回自己的缓存。

另一个 CPU 同样的处理,就导致可能看不到上一个 CPU 处理的结果。

线程切换带来的原子性问题

程序中的一行代码往往不是一条 CPU 指令。

线程切换的时候,可能会在一个代码执行的中间地方切换。

编译优化带来的有序性问题

优化会为了更高效的利用 CPU 缓存,将代码指令重排。

这个重排的过程会导致看似没问题的代码,多线程出现逻辑问题。

三、为啥要遇到这些问题

  • 为了提高程序的性能
  • 引入了新方法,就要处理这个方法对应的问题
  • 可以说是硬件工程师和操作系统工程师为了提高执行效率,给软件工程师带来的麻烦

接下来的几篇文章会介绍如何解决上面提到的「可见性、原子性、有序性」的问题。

【Java并发入门】01 并发编程Bug的源头的更多相关文章

  1. 【转】可见性、原子性和有序性问题:并发编程Bug的源头

    如果你细心观察的话,你会发现,不管是哪一门编程语言,并发类的知识都是在高级篇里.换句话说,这块知识点其实对于程序员来说,是比较进阶的知识.我自己这么多年学习过来,也确实觉得并发是比较难的,因为它会涉及 ...

  2. 01 | 可见性、原子性和有序性问题:并发编程Bug的源头

    由于CPU.内存.I/O 设备的速度差异,为了合理利用 CPU 的高性能,平衡这三者的速度差异,计算机体系机构.操作系统.编译程序都做出以下处理: 1. CPU 增加了缓存,以均衡与内存的速度差异: ...

  3. Java并发编程实战 01并发编程的Bug源头

    摘要 编写正确的并发程序对我来说是一件极其困难的事情,由于知识不足,只知道synchronized这个修饰符进行同步. 本文为学习极客时间:Java并发编程实战 01的总结,文章取图也是来自于该文章 ...

  4. 并发编程Bug起源:可见性、有序性和原子性问题

    以前古老的DOS操作系统,是单进行的系统.系统每次只能做一件事情,完成了一个任务才能继续下一个任务.每次只能做一件事情,比如在听歌的时候不能打开网页.所有的任务操作都按照串行的方式依次执行. 这类服务 ...

  5. 【Java并发基础】并发编程bug源头:可见性、原子性和有序性

    前言 CPU .内存.I/O设备之间的速度差距十分大,为了提高CPU的利用率并且平衡它们的速度差异.计算机体系结构.操作系统和编译程序都做出了改进: CPU增加了缓存,用于平衡和内存之间的速度差异. ...

  6. 从缓存入门到并发编程三要素详解 Java中 volatile 、final 等关键字解析案例

    引入高速缓存概念 在计算机在执行程序时,以指令为单位来执行,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入. 由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这 ...

  7. Java:并发笔记-01

    Java:并发笔记-01 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 1. 进程与线程 本章内容 进程和线程的概念 并行和并发的概念 线程基本应用 1.1 ...

  8. 《java学习二》并发编程

    多线程创建方式 1.继承thread类,重写run方法 CreateThread createThread = new CreateThread();     ------createThread  ...

  9. Java并发入门之FutureTask

    Java并发入门之FutureTask 前言: 最近遇到一个项目需要上传图片到服务器,API要求是二进制流,那就跑慢点一点点上传. 于是对多线程从没有应用过的我,决定拿多线程直接应用于代码. 应用Ex ...

  10. Java 面试宝典!并发编程 71 道题及答案全送上!

    金九银十跳槽季已经开始,作为 Java 开发者你开始刷面试题了吗?别急,我整理了71道并发相关的面试题,看这一文就够了! 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程( ...

随机推荐

  1. 倾斜摄影技术构建图扑 WebGIS 智慧展馆

    前言 智慧展馆通过"云大物移智链"等技术将"物"(展品.设备.环境等)进行互联,并感知"人"(工作人员.观众等)的行为.结合 GIS.BIM ...

  2. 入门篇-其之七-Java运算符(下)

    一.三元运算符的使用 三元运算符(也称作三目运算符),使用:和?表示,其格式为:布尔表达式 ? 表达式1 : 表达式2 如果布尔表达式的计算结果是true,那么执行表达式1:否则,如果布尔表达式的计算 ...

  3. 高级数据结构---B树和B+树及mysql索引分析

    mysql索引数据结构:https://www.cnblogs.com/nijunyang/p/11406688.html 几种树结构的对比: 二叉查找树:二叉搜索树,二叉排序树,优点查找快,但是在某 ...

  4. vue结合element-ui实现多层复选框checkbox

    1.需求如上图所以: html相关代码如下: 1 <div class="intent-course-wrapper"> 2 <div class="c ...

  5. maven总结二: 常用标签及属性

    本文为博主原创,未经允许不得转载  目录: 1. maven 依赖属性:groupId.artifactId.version 2.插件执行: execution,id ,phase,goals,con ...

  6. 在虚拟机(Linux)中Docker中部署Nginx成功,但是在宿主机无法访问Nginx站点?

    1.问题 本文是基于黑马程序员Docker基础--常见命令一课中部署Nginx时遇到的问题作出解答. 在虚拟机(Linux)中Docker中部署Nginx成功,但是在宿主机无法访问Nginx站点 如图 ...

  7. WebApi使用Swagger

    services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API ...

  8. [转帖]prometheus的TCP alloc取值

    prometheus的TCP alloc取值 sockets: used:已使用的所有协议套接字总量 TCP: orphan:无主(不属于任何进程)的TCP连接数(无用.待销毁的TCP socket数 ...

  9. [转帖]CentOS7使用Chrony实现时间同步

    学习安装部署 ceph 时 ,在添加 mon 时报错了,搜索原因后发现是 时间同步问题.于是学习一下时间同步工具. 一般CentOS6 使用的时间同步工具是ntp.现在还有不少开源软件文档建议安装的时 ...

  10. 【转帖】Linux性能优化(十三)——CPU性能测试

    一.CPU上下文切换测试场景 使用sysbench模拟多线程调度: sysbench --threads=10 --time=300 threads run 使用vmstat查看CPU上下文切换: c ...