ing 发表于 2022-4-6 22:59

多线程访问共享变量看不到最新值

本帖最后由 ing 于 2022-4-7 10:31 编辑

----------------------------------------------------------------------文末已得出问题的结论,如果有误还请指正----------------------------------------------------------------------
我不知道为什么子线程休眠一段时间再修改flag就会导致主线程读取的flag变量一直都是未修改过的值(为什么子线程休眠会造成程序执行结果的不同?)






这张图片的解释让我更加迷惑,第四段说while是底层代码执行速度快到没时间读取主存的值所以主线程的值从主线程的工作内存读取,这样就导致主线程看不到最新值(即图2执行的结果);
可是如果 线程休眠 被注释掉,主线程却可以看到修改后的值(即图1执行的结果),这是为什么?


___________________________________________________________________________
为什么子线程休眠会造成程序执行结果的不同,这是我得出的结论
让子线程休眠一段时间确保子线程和主线程从主内存拷贝变量副本到各自工作内存的时候都是一致的false,避免主线程读取到工作内存中的是子线程修改后的值(flag=true);
我试过多次执行 图2 注释掉休眠后的代码,我想如果主线程在子线程执行flag=true之前执行到了get方法读取flag值(false),那么就可以达到图1的效果(实际上,如果不休眠子线程,flag=true的执行速度太快即使多次执行也未能触发图1的效果)

ing 发表于 2022-4-6 23:09

刚发完就想明白了,线程休眠的作用是不让主线程的工作内存读取到修改后的值,这样while循环读取工作内存的值就一直是未修改的值

goldli 发表于 2022-4-7 07:10

本帖最后由 goldli 于 2022-4-7 07:16 编辑

ing 发表于 2022-4-6 23:09
刚发完就想明白了,线程休眠的作用是不让主线程的工作内存读取到修改后的值,这样while循环读取工作内存的 ...
线程休眠的作用是不让主线程的工作内存读取到修改后的值


通过这句话,我就知道你对线程一无所知。
首先你得明白,计算机在进行任务调度时是可以多任务(当前计算机)。 但是执行任务时是单个执行的。多任务同时执行只是人类感观上的。实际上是由CPU根据任务优先级,时间片等等条件来轮询执行的。
在程序代码中的 Thread.Sleep 的首要目的是 让出占用的CPU资源, 从而让CPU执行其它任务。

你要进行线程间内存共享, 最好的办法是执行 共享内存 所在的 类 的某个方法, 而在此方法中使用锁 来进行处理。

finky 发表于 2022-4-7 08:23

ing 发表于 2022-4-6 23:09
刚发完就想明白了,线程休眠的作用是不让主线程的工作内存读取到修改后的值,这样while循环读取工作内存的 ...

不是的,线程休眠是让出时间片而已

夏橙M兮 发表于 2022-4-7 08:53

goldli 发表于 2022-4-7 07:10
线程休眠的作用是不让主线程的工作内存读取到修改后的值




那么多核cpu呢?应该是并行执行任务吧。

ing 发表于 2022-4-7 09:58

finky 发表于 2022-4-7 08:23
不是的,线程休眠是让出时间片而已

没错,我的意思就是要子线程让出CPU执行的时间片,确保子线程和主线程从主内存拷贝变量副本到各自工作内存的时候都是一致的false,避免主线程读取到工作内存中的是子线程修改后的值(flag=true)

ing 发表于 2022-4-7 10:00

夏橙M兮 发表于 2022-4-7 08:53
那么多核cpu呢?应该是并行执行任务吧。

单核也可以达到并行效果的哦,可以看看我给 的回复

zhiwoda 发表于 2022-4-7 10:14

voliate int i;
页: [1]
查看完整版本: 多线程访问共享变量看不到最新值