线程的内存分配:每个线程都有自己的工作内存,通过工作内存和主线程来同步数据。
使用volatile后的内存:直接从主内存中来读取数据
其主要区别就是从内存中读取与写入数据的方式是不是通过线程自身的工作内存。
结论:使用volatile并不能保证同步,但是可以保证线程所读取到的数据是最新的。
不实用volatile出现的情况:a线程写入到主内存,但此时b线程读的是工作内存,并不是主内存,数据不是最新鲜的
测试代码:会出现异常的情况
public class UnsafeThread implements Runnable{
private volatile int count = 0;
public void run(){
for(int i=0; i<1000; i++){
Math.hypot(Math.pow(92456789, i), Math.cos(i));
}
count++;
}
public int getCount(){
return count;
}
public static void main(String[] args) throws Exception {
int value = 100;
int loops = 0;
ThreadGroup tg = Thread.currentThread().getThreadGroup();
while(loops<value){
UnsafeThread ut = new UnsafeThread();
for(int i=0; i<value; i++){
new Thread(ut).start();
}
do{
Thread.sleep(15);
}while(tg.activeCount() != 1);
if(ut.getCount() != value){
System.out.println("循环到第 "+loops+" 遍出现异常!");
System.out.println("此时count= "+ut.getCount());
System.exit(0);
}
loops = loops + 1;
}
}
}