java内存模型,可以理解为变量的访问规则,在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。 线程、主内存、工作内存的交互关系如下: 8种内存交互操作: lock: unlock: read: load: use: assign: store: write: volatile关键字作用 1可见性:保证变量对所有线程可见 普通变量的值在线程间传递均需要通过主内存完成,volatile变量也是如此。例如线程A修改一个普通变量的值,然后向主内存进行回写,另外一条线程B在线程A回写完成之后再从主内存进行读取操作,新变量值才会对线程B可见。volatile的特殊规则保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新。volatile变量对所有线程是立即可见的(在各个线程的工作内存中,volatile变量也可以存在不一致的情况,但每次使用之前都要先刷新,执行引擎看不到不一致的情况,因此可以认为不存在不一致的问题) 2非原子性
package extthread; public class MyThread extends Thread{ public static int count; private static void addCount(){ for(int i=0;i<100;i++){ count++; } System.out.println("count="+count); } @Override public void run(){ addCount(); } } package extthread; public class Run { public static void main(String[] args){ MyThread[] mythreadArray=new MyThread[100]; for(int i=0;i<100;i++){ mythreadArray[i]=new MyThread(); } for(int i=0;i<100;i++){ mythreadArray[i].start(); } } }打印结果:count=9137 原因:表达式i++的操作步骤: 1)从内存中取出i的值 2)计算i的值 3)将i的值写到内存中 假如某一线程在第2步计算值的时候,另一个线程也修改了i的值,这个时候就会出现脏读数据的情况,解决办法是使用synchronized关键字修饰。volatile本身并不处理数据的原子性,只是强制对数据的读写及时影响到主内存。 3禁止指令重排序优化
