老师,关于内存可见性问题,以及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++操作是怎么执行的?他们的本地内存中缓存的是啥?