文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

基于多线程并发的常见问题(详解)

2023-05-31 01:05

关注

一 概述

1.volatile

保证共享数据一旦被修改就会立即同步到共享内存(堆或者方法区)中。

2.线程访问堆中数据的过程

线程在栈中建立一个数据的副本,修改完毕后将数据同步到堆中。

3.指令重排

为了提高执行效率,CPU会将没有依赖关系的指令重新排序。如果希望控制重新排序,可以使用volatile修饰一个变量,包含该变量的指令前后的指令各自独立排序,前后指令不能交叉排序。

二 常见问题及应对

1.原子性问题

所谓原子性,指的是一个操作不可中断,即在多线程并发的环境下,一个操作一旦开始,就会在同一个CPU时间片内执行完毕。如果同一个线程的多个操作在不同的CPU时间片上执行,由于中间出现停滞,后面的操作在执行时可能某个共享数据被其他线程修改,而该修改并未同步到当前线程中,导致当前线程操作的数据与实际不符,这种由于执行不连贯导致的数据不一致问题被称作原子性问题。

2.可见性问题

可见性问题的出现与线程访问共享数据的方式有关。线程访问堆(方法区)中的变量时,先在栈中建立一个变量的副本,修改后再同步到堆中。如果一个线程刚建立副本,这时另一线程修改了变量,尚未同步到堆中,这时就会出现两个线程操作同一变量的同一种状态的现象,比如i=9,变量i的初始值为9,每一个线程的操作都是减1。两个线程A与B同时访问变量,B先执行i-1,在将结果i=8同步到堆中前,A线程也执行i-1,这时i=9的状态就被执行两次,出现线程安全问题。

线程安全问题产生的原因:一个线程对共享数据的修改不能立即为其他线程所见。

volatile提供了一种解决方案:

一旦一个线程修改了被volatile修饰的共享数据,这种修改就会立即同步到堆中,这样其他数据从堆中访问共享数据时始终获得的是在多个线程中的最新值。

volatile的缺陷:

volatile只能保证一个线程从堆中获取数据时获取的是当前所有线程中的最新值,假如一个线程已经从堆中复制了数据,在操作完成前,其他线程修改了数据,修改后的数据并不会同步到当前线程中。

3.有序性问题

为了提高执行效率,CPU会对那些没有依赖关系的指令重新排序,重新排序后的执行结果与顺序执行结果相同。

例如,在源代码中:

int i=0;int y=1;

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 资料下载
  • 历年真题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯