对多线程原子性的理解
2023-03-31 10:46:15 时间
多线程原子性的理解:一个操作要么全部执行完毕,不会受到干扰而被中断;要么全都不执行
- 对于多线程中操作共享变量的操作,要保证它的原子性。
- 以下是对一个非原子性操作的分析:
- 在一个类中有共享变量count,开启一百个线程对其进行count++操作,每个线程对count加一百次。
- count变量是属于共享变量,在每个线程操作它的时候,需要先把它读取到自己的工作内存中。
- 如果说A线程读取了count,这时候cpu分配了时间片给B线程,B线程也读取到了count,并且进行了count++操作,但是还没有写回主内存。
- 这时候cpu分配时间片给A线程,它进行count++操作,同时写会主内存,又分配给线程B,同时将操作写会主线程。
- 这就属于线程A的操作被线程B干扰而中断,最终导致count只被修改了一次,并没有确保原子性。
为什么volatile不能保证原子性呢
对volatile机制解释
- 被volatile修饰的变量account。如果说线程A对account进行了修改,并且将该数据写回了主内存,那么会使得其他线程工作内存中的account关键字失效。
- 如果其他线程需要操作该count,那么会再次从主内存中拿到自己的工作内存中。这样就解决了共享变量的可见性。
回归正题
- 对于像上面那个非原子性操作count的例子中:A读取到了count,B读取到了count并修改,但是没写回。
- 然后又到线程A,A执行了修改并且写会。这时候又到B线程,但是B此时已经不需要再对count操作了
- 不对共享变量操作,那么不会再去主内存中读值再操作。也就是B线程会直将数据写会到主内存。也就是说volatile无法保证原子性。
而对于synchronized
- 它可以保证原子性,因为只有拿到锁的线程可以操作共享变量count,而其他线程会被阻塞。保证了当前线程不会收到干扰而中断。
相关文章
- Ansible 起步指南
- LXD 2.0 系列(五):镜像管理
- 完全指南之在 Ubuntu 操作系统中安装及卸载软件
- 在 Linux 终端中自定义 Bash 配色和提示内容
- 在 Linux 中管理设备
- 《云数据管理:挑战与机遇》一第二章
- 在 iSCSI Target 服务器中使用LVM创建和设置LUN(二)
- 学习和使用 PHP 应该注意的10件事
- CentOS 上的 FirewallD 简明指南
- 《云数据管理:挑战与机遇》一2.2P2P系统
- 如何使 GDebi 默认代替 Ubuntu 软件中心
- 从源代码编译 Vim 8.0
- 如何在 Linux 中找出最近或今天被修改的文件
- 十个提升生产力的 bash 技巧
- 设置iSCSI的发起程序(客户端)(三)
- Samba 系列(三):使用 Windows 10 的 RSAT 工具来管理 Samba4 活动目录架构
- 如何在 Ubuntu 16.10 的 Unity 8 上运行老式 Xorg 程序
- Linux桌面环境终极指南
- 如何在 Ubuntu 环境下搭建邮件服务器(三)
- Linux有问必答:如何在Debian或Ubuntu上安装完整的内核源码