多线程,static变量与volatile

Sxm& 2019-06-24 04:01:47


static变量加载到了不同线程的各自工作缓存中,为什么B线程对init变量值的修改在A线程中可见了,这边并未使用volatile修饰init。但是在A线程中添加局部变量后,B线程对init值的修改就对A线程的init值没有影响了,这时A线程中的init一直是0
...全文
340 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_39936465 2019-06-25
  • 打赏
  • 举报
回复
如果线程内变量不失效的话,它会一直使用自己内存中保存的该变量的数据,而不会去主线程中重新读取。
qq_39936465 2019-06-25
  • 打赏
  • 举报
回复 1
引用 3 楼 xianmingsu 的回复:
没看太明白,是说init这个static变量被分别加载到A和B两个线程的工作缓存中,因为init变量没有被volatile修饰,所以B线程对init值的修改刷回主内存后,对A线程中工作缓存中的init值没有影响,因为A线程没有执行println(init),所以A线程不会重新载入主内存中的值,就一直是0,是这样子吗
个人理解,主程序 有主程序的内存, 线程也有自己的独立内存,全局变量需要线程去主程序内存读取数据保存在自己的内存中,线程不会频繁去主程序中读取变量的当前数据这样做会很没效率,而写入时不会有这种情况,因为是全局变量线程在写入数据时,会发送一份新数据给主程序接收后会更新该数据。volatile这个关键字的作用是每当主程序变量数据被改变时,线程中的该变量就会失效,线程在下次使用时会再次从主程序重新读取数据,而print这个语句也能起到这个效果。
_飞翔的蜗牛 2019-06-24
  • 打赏
  • 举报
回复
每个线程都有自己的一个内存空间,当它第一次从主内存中读取变量的值时,就把变量的值存放在该线程自己的内存空间中,以后在运行的时候,该线程就会从自己的内存中去用该变量的值,而不是从主内存中读取该变量的值,volatile关键字修饰的变量就会使线程每次都会去读取主内存中的变量的值,而不是从自身的内存中读取
Sxm& 2019-06-24
  • 打赏
  • 举报
回复
没看太明白,是说init这个static变量被分别加载到A和B两个线程的工作缓存中,因为init变量没有被volatile修饰,所以B线程对init值的修改刷回主内存后,对A线程中工作缓存中的init值没有影响,因为A线程没有执行println(init),所以A线程不会重新载入主内存中的值,就一直是0,是这样子吗
qq_39936465 2019-06-24
  • 打赏
  • 举报
回复
上面拼写除问题,应该是A线程中的全局变量init被重载
qq_39936465 2019-06-24
  • 打赏
  • 举报
回复
引用 楼主 xianmingsu 的回复:
static变量加载到了不同线程的各自工作缓存中,为什么B线程对init变量值的修改在A线程中可见了,这边并未使用volatile修饰init。但是在A线程中添加局部变量后,B线程对init值的修改就对A线程的init值没有影响了,这时A线程中的init一直是0
一般数据从内存中载入后,jvm不会频繁再次重载数据,而print打印语句会引发当前数据失效,重新载入内存中的数据,所以等于实现了volatile的效果此时变量init全局被重载,init数据被加载入新数据。而第2段程序A线程由于没有执行print语句,jvm不会对数据重载,所以init始终是0
  • 举报
回复
@qq_39936465 public static boolean flag=true; public static void main(String[] args) throws InterruptedException { Thread one = new Thread(() -> { log.info("{}当前线程 开始执行,flag:{}", Thread.currentThread().getName(), flag); while (flag) { continue; } log.info("{}当前线程 结束执行,flag:{}", Thread.currentThread().getName(),flag); },"while线程"); Thread other = new Thread(() -> { log.info("{}当前线程 开始执行,flag:{}", Thread.currentThread() .getName(), flag); flag=false; log.info("{}当前线程 结束执行,flag:{}", Thread.currentThread().getName(),flag); },"change线程"); other.start(); one.start(); } 大佬,帮我看一下这个程序,线程while 为什么会跳出循环。

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧