多线程访问共享数据同步原因
来源:互联网 发布:js 判断event 编辑:程序博客网 时间:2024/06/05 19:29
首先,JVM中堆空间(存放对象)、方法区(存放静态变量、常量)、常量池(String常量池、整形常量池)是线程共享的空间,Java栈空间是线程私有的,每个线程都有一个栈空间,执行一个方法时会创建一个栈帧,压入栈中,栈帧中保存局部变量、方法参数、中间变量的值,方法返回后栈帧弹出。线程读取堆、方法区、常量池中数据后,存放在线程栈中,对栈中的值操作完成后,再写回堆、方法区、常量池中,如果多个线程同时改动共享数据的话,可能会出现一个线程操作后的结果被其他线程返回的结果覆盖掉(同时写)或者一个线程读取到的数据是其他线程改动后的结果(一个线程读、一个线程写)。所以要对共享数据(共享内存中的数据)进行同步,一个时刻只能有一个线程进行写操作,该线程执行完成后,其他线程才能访问。
如果线程1从方法区(线程共享空间)复制变量到当前线程栈内存后,修改完成,还没写回方法区前,此时其他线程执行了写操作并写回了方法区,然后线程1将结果写回方法区,会导致其他线程的操作结果被线程1覆盖。
例如下面的例子,1000个线程同时对共享变量count进行加1,所有线程执行结束后,count值理应是1000,然而结果并非总是1000.
public class Main { public static int count = 0; public static void countNum() { //休眠一毫秒,结果更明显 try{ Thread.sleep(1); } catch(Exception e) { } count++; } public static void main(String[] args) { //同时启动1000个线程,每个线程加1,观察实际结果是否是1000 for(int i=0;i<1000;i++) { new Thread(new Runnable() { public void run() { Main.countNum(); } }).start(); }//每次运行的结果都有可能不同,可能1000 System.out.println("结果是:"+Main.count); }}
如果线程1从方法区(线程共享空间)复制变量到当前线程栈内存后,修改完成,还没写回方法区前,此时其他线程执行了写操作并写回了方法区,然后线程1将结果写回方法区,会导致其他线程的操作结果被线程1覆盖。
阅读全文
0 0
- 多线程访问共享数据同步原因
- 代码笔记 | 多线程使用queue模块同步访问共享数据
- 多线程同步,多线程数据共享
- 多线程同步访问共享内存
- 多线程写操作导致结果不正确的原因(为什么要对共享数据同步)
- 对共享可变数据的同步访问
- 并发-同步访问共享的可变数据
- UNIX多线程数据共享与线程同步
- UNIX多线程数据共享与线程同步
- synchronized解决多线程共享数据同步问题
- Java多线程共享数据、同步、通信
- 多线程访问共享数据的Bug
- 多线程访问共享数据(1)
- 多线程访问共享数据(2)
- 多线程访问共享数据的安全问题
- 多线程访问共享数据(1)
- 多线程访问共享数据(2)
- 多线程要访问共享数据的方式
- 【WPS技能】xlsx表格根据单元格的值改变行背景色
- java开发环境搭建
- Error:(171, 0) No such property: sdkHandler for class: com.android.build.gradle.LibraryPlugin
- codeforces 666E Forensic Examination
- [Office][Excel][001]如何将一行数据拆成多行?
- 多线程访问共享数据同步原因
- hibernate一对多与多对一映射
- 学习淘淘商城第一百零八课(Mycat的读写分离)
- 单链表中求倒数第几个节点
- C++ 中一些零碎的知识点
- CF
- selvet的生命周期
- Hbase 热点(数据倾斜)问题解决方案---rowkey散列和预分区设计
- 用Caffe+python如何训练一个手写体数字数别模型