Java内存模型以及volatile关键字详解
1 package com.company; 2 4 public class VolatileVisibilityTest { 5 private static boolean initFlag=false; 6 public static void main(String[] args) throws InterruptedException { 7 new Thread(new Runnable() { 8 @Override 9 public void run() { 10 System.out.println("waiting data..."); 11 while (!initFlag) { 12 } 13 System.out.println("Success"); 14 } 15 }).start(); 16 18 Thread.sleep(2000, 0); 19 20 21 new Thread(new Runnable() { 22 @Override 23 public void run() { 24 prepareData(); 25 } 26 }).start(); 27 } 28 public static void prepareData(){ 29 System.out.println("preparing data..."); 30 initFlag=true; 31 System.out.println("prepare end..."); 32 } 33 }大家可能会认为出现下面的结果:
waiting data...
preparing data...
prepare end...
Success
结果真的是这样的吗?下面我就启动main方法,演示结果如下
waiting data... preparing data... prepare end...并没有打印出Success,大家可能会奇怪下面的线程已经把initData变量改成了true,上面的线程应该会跳出死循环,打印出Success。 我们搜索csdn查看什么是Java内存模型的原子操作,给出的解释如下,大家一脸懵逼,这说的啥意思:
-server -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,*VolatileVisibilityTest.prepareData3.执行main方法,代码太多, volatile底层也是加lock锁来实现缓存一致性协议,那么他与总线加锁有什么区别呢? volatile只对内存的缓存行进行加锁,然后进行赋值操作。 并发编程的三大特性:可见性,原子性,有序性 volatile保证可见性与有序性,但是不保证原子性,保证原子性需要借助synchronized关键字 如何理解上面这句话的意思呢?下面我再给大家举一个栗子
package com.company; public class VolatileAtomicTest { public static volatile int num=0; public static void increase(){ num++; } public static void main(String[] args) throws InterruptedException { Thread[] threads=new Thread[10]; for (int i = 0; i < threads.length ; i++) { threads[i] = new Thread(new Runnable() { @Override public void run() { for (int j = 0; j <1000 ; j++) { increase(); } } }); threads[i].start(); } for(Thread t:threads){ t.join(); } System.out.println(num); } }大家猜一猜,上面的程序运行后的结构是多少呢? 先抢到锁的线程会把没有抢到锁的线程的值失效掉 说完了可见性、原子性,最后我给大家讲一讲有序性
package com.company; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class VolatileSerialTest { static int x=0,y=0; public static void main(String[] args) throws InterruptedException { Set<String> resultSet=new HashSet<>(); Map<String,Integer> resultMap=new HashMap<>(); for (int i = 0; i <10000 ; i++) { x=0;y=0; resultMap.clear(); Thread one =new Thread(new Runnable() { @Override public void run() { int a=y; x=1; resultMap.put("a",a); } }); Thread other =new Thread(new Runnable() { @Override public void run() { int b=x; y=1; resultMap.put("b",b); } }); one.start(); other.start(); one.join(); other.join(); resultSet.add("a="+resultMap.get("a")+","+"b="+resultMap.get("b")); System.out.println(resultSet); } } }
大家想一想,上面输出的结果是多少呢?运行程序,最后会出现四种情况。 大家思考一下,为什么? 优质内容筛选与推荐>>