JMM内存模型相关

2020-05-02 261 ℃

JMM(线程)内存模型

image.png
image.png

  • 流程:每一个线程都会把共享变量复制一份到工作内存中,叫共享变量副本,依次来做一系列操作

下面来看一段代码:

public class Demo2 { private static boolean flag = false; public static void main(String[] args) throws InterruptedException { new Thread(() ->{ System.out.println("等待flag变True"); while (!flag){} System.out.println("flag已变成Ture"); }).start(); Thread.sleep(2000L); new Thread(() ->{ System.out.println("准备把flag改为True......"); flag = true; System.out.println("已经把flag改为True"); }).start(); } }

打印的结果是:
image.png

没有如所愿那样,打印出另外一行。
解决方法:
加个关键字:voletile
image.png

JMM数据原子操作

image.png

缓存不一致解决方案

image.png
image.png
image.png

votatile具有可见性,有序性,但是没有原子性

举个栗子,看代码:

package com.company; public class Demo3 { private static volatile int num = 0; private synchronized static void increase() { num ++; } public static void main(String[] args) throws InterruptedException { Thread[] threads = new Thread[10]; for (int i = 0; i< threads.length ;i ++){ threads[i] = new Thread(() ->{ for (int j = 0 ; j < 1000 ; j++){ increase(); } }); threads[i].start(); } for (Thread t :threads){ t.join(); } System.out.println(num); } }

最后打印的结果是: <= 10000。
image.png
具体原因:在多线程对一个值做操作的时候,由于存在cpu总线嗅探机制,会导致慢一点的线程做的++操作都白+了,所以该次加法会无效(白加了)。

版权声明:冰雨stack原创文章,转载请注明出处。

发表时间:2020-05-02 23:50

最后更新时间:2020-05-03 11:48