美文网首页
无法用直觉发现的并发bug

无法用直觉发现的并发bug

作者: 牡丹男孩 | 来源:发表于2019-07-23 22:59 被阅读0次
一、开始前先普及下基础知识

1、多核cpu,每颗cpu上都有缓存。线程不在同一个核上执行,会出现变量修改可见性问题,最后出现cpu缓存与内存的数据不一致。

2、速度:cpu>内存>io,为了充分利用cpu,不被io速度限制,操作系统使用多进程来实现边听歌边聊QQ--每50毫秒选择一个进程来执行(任务切换),50毫秒称为时间片。现在操作系统都是基于更轻量的线程调度,现在的任务切换即线程切换。

3、cpu都是基于指令来执行的,不是高级语言的一条语句,一条语句往往都是有多条指令来完成的。比如执行n = n+1 ,三条指令 (1)n从内存到寄存器(2)寄存器执行n+1(3)将结果写入内存/cpu缓存。

4、编译器会为了优化性能,改变语言的编译顺序,比如先给你初始化内存空间,再进行其他操作。

二、并发问题的出现

1、并发程序都是基于多线程的,由于多核cpu缓存可见性问题,不同线程在操作一共享变量时就会出现结果的不一致情况。

2、假设在单核cpu上根据时间片进行线程切换,当线程一组指令执行一半的时候切换另一线程执行另一组命令,这时就会出现原子性问题。如果两条线程同时执行n = n+1这一组命令,A线程将n=0命令加载到寄存器这时线程切换B线程执行完全部命令将结果1更新到内存,接着A线程继续执行再将结果1更新到内存。

3、编译优化造成的问题,根据语句的执行顺序是123、编译过后可能变成213。比如A线程执行这组命令先去分配内存地址给对象,此时对象成员变量还没初始化。这时线程切换另一线程也进来执行发现对象非null直接返回,造成使用对象成员变量空指针异常。

三、并发问题解决

1、通过语言提供的保证可见性的关键之修饰变量使得每个线程操作结果可见即让cpu缓存失效。

2、通过同步的方式使变量同一时间只能一条线程访问保证原子性(会堵塞)

3、乐观锁,有3个操作数,内存值V,旧的值A,要修改的新值B。当内存的值和旧的值一致允许线程修改成B值,否则放弃修改重新尝试。

相关文章

  • 无法用直觉发现的并发bug

    一、开始前先普及下基础知识 1、多核cpu,每颗cpu上都有缓存。线程不在同一个核上执行,会出现变量修改可见性问题...

  • JNI开发报错 JNI DETECTED ERROR IN AP

    在之前用JNI进行AES加密中,发现偶发bug,报错信息清理如下: 后发现是在JNI的AES加密,在并发的时候,会...

  • 深拷贝的用法

    在后续操作中发现遇到了bug, 这里由于clone后发现无法用sort和filter,报错Parameter 'b...

  • Java并发一:Java并发编程三大核心

    编写并发程序是比较困难的,因为并发程序极易出现Bug,这些Bug有都是比较诡异的,很多都是没办法追踪,而且难以复现...

  • go并发(一)

    前几天被小伙伴发现半年前写的代码里面有一个并发的bug。回想一下,golang并发这边的知识确实忘得差不多了,打算...

  • 【转载】Java并发编程系列02 | 并发编程三大核心问题

    写在前面 编写并发程序是比较困难的,因为并发程序极易出现Bug,这些Bug有都是比较诡异的,很多都是没办法追踪,而...

  • PHPexcel导出图片+文字

    导入包下载....中间出了点bug,无法导出 发现这个包只能5.5+

  • 直觉发现的问题

    萨哈泼/文 真实的描述一件事情,这件事已经是过去式了,具体的环境,人物就不描述了,就是觉得,女人的直觉真的挺可怕,...

  • 发现bug

    有了新的贝壳小岛,在一定程度上提振了简书的热度,只是小岛还处于运营初期,相对的还存在交易量不足的问题。但是只要有小...

  • 发现bug,解决bug

    于我们这些追求每天进步的人来说,可能时常就会有这样的烦恼: 你发现自己竟然有那么多不足? 然后,这一个念头就会被你...

网友评论

      本文标题:无法用直觉发现的并发bug

      本文链接:https://www.haomeiwen.com/subject/knhzlctx.html