内存可见性,以及Java内存模型和JVM内存结构的问题
来源:2-3 八大基础的重点

深海的星星15138
2020-04-23
老师,关于内存可见性问题,以及Java内存模型和JVM内存结构,我有个小疑问。可见性问题是由于工作内存和主内存的内容同步问题导致的。工作内存和主内存是Java内存模型抽象出来的,工作内存是每个线程独有的,主内存是所有线程共享的。在JVM内存结构中,只有栈(两种)和程序计数器是线程独有的,堆和方法区是线程共享的。不知道我这里有没有说错。如果没说错那请问JMM抽象出来的工作内存和主内存,与JVM内存结构之间有什么联系吗?有这个疑问是因为,对象是存储在堆上的,也就是线程共享的区域,那么对一个对象属性的修改,不应该是直接修改主内存的吗,在这种情况上下,为啥会有可见性问题呢?换句话说,关于堆中的对象,线程的工作内存中缓存的是什么呢?
public class Main {
private static class Task implements Runnable {
int a;
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
this.a++;
}
}
}
public static void main(String[] args) throws InterruptedException {
Task task = new Task();
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(task.a);
}
}
以您讲的经典的多线程a++的问题为例,这个task对象是在堆上的吧,它的属性a也在堆上,那t1和t2两个线程的a++操作是怎么执行的?他们的本地内存中缓存的是啥?
1回答
-
深海的星星15138
提问者
2020-04-23
我觉得是这样的,JVM内存结构,与JMM抽象出来的工作内存和主内存没什么关系,因为他俩本身讨论东西的角度就不一样。JVM内存结构中说的那些区域的“共享”和“私有”,指的就是固有的共享和私有,就是说栈、程序计数器这些东西,它就是每个线程有一份,这里的共享和私有之间也不存在同不同步的问题;而JMM说的工作内存和主内存的“共享”与“私有”,指的是线程在运行期间,会有多级缓存,有些缓存是依附于CPU的,所以是私有的,而数据都是存在RAM中的,所以是共享的,这里的共享和私有是有同步问题的,因为CPU操作的都是自己工作内存中的数据,这些数据需要flush回主存才生效,而工作内存中的内容也存在过期的问题。
所以关于上面那个问题:
“线程的工作内存中缓存的是什么”,我觉得,只要是从RAM里读的东西都会缓存,而关于JVM内存结构中的堆、对象存储在堆上而堆是线程共享的,这些东西是不用考虑的,因为他们讨论的是不同的东西。
“这个task对象是在堆上的吧,它的属性a也在堆上,那t1和t2两个线程的a++操作是怎么执行的”,我觉得,task和它的属性a的确是存在堆上,但这里所说的“堆”,也只是JVM内存结构抽象出来的、在RAM中的一块区域,说白了还是RAM中的数据。对于a++操作,t1和t2从RAM里读出a到本地内存,再加1,再将结果刷回RAM,这个过程不用考虑task对象是存储在JVM内存结构中的堆中的,因为他们讨论的是不同的东西。
不知道我这样理解对不对。
022020-04-25
相似问题