每个线程都会有自己独立的工作内存,当线程需要使用主内存中的某个变量时将会把主内存中的变量拷贝一份放入工作内存,而当两个线程同时使用了一个内存变量,当其中一个线程改变了改变了该变量的值,由于另一个线程还在处于工作状态,没来的及将工作内存中的值更新过来,就会造成使用的还是原来的值 。
JMM体现在以下几个方面:
- 原子性-如何保证指令不会受到线程上下文切换的影响。线程上下文切换主要指运行态和阻塞态之间的转换,这个切换消耗成本较大
- 可见性-如何保证指令不受工作内存(cpu缓存)的影响
- 有序性-如何保证指令不受cpu指令并行优化的影响
synchronized可以保证原子性、可见性,线程中只要遇到synchronized锁,就会从主存中更新工作内存。但是synchronized关键字不能保证有序性。
A a=new A();
1.开辟一块内存空间(空白内存空间)
2.对象初始化(属性赋初值等)
3.将引用赋予变量a
在很多线程做线程优化时顺序往往时132(这就是指令重排)
我们可以看到当线程将stop读取到自己的工作内存时一直处于工作状态,而将主线程将主存中的值改了之后,该线程读的还是自己工作内存中的值,并没有停下来的迹象。
而我们如果可以让该线程在运行中睡眠一会,将cpu让给别人,那么这是就将会更新数据。
也就是说,当变量的操作在被锁定的代码块中,线程进入这段代码时,会自动将主存的数据更新到工作内存中,离开这段代码前会将工作内存的数据回写在主存中。