JMM(java内存模型)
JMM三个特征:
原子性:一个操作不能被打断,要么全部执行完毕,要么不执行。在这点上有点类似于事务操作,要么全部执行成功,要么回退到执行该操作之前的状态。
有序性:单线程程序里代码是从前往后执行,但对于多线程并发执行出现乱序
可见性:一个线程对共享变量做了修改之后,其他的线程立即能够看到(感知到)该变量的这种修改(变化)。
JMM内存模型
(1)主内存是共享内存区域,所有变量都存在主内存中,所有线程都可以访问;
(2)各个线程的工作线程相互独立和隔离;
(3)线程操作变量必须先从主内存中读取变量信息,然后在工作内存中进行修改,最后再写会主内存中,修改才会生效
Volatile
volatile关键字可以保证共享变量可见性和有序性。
public class VolatileTest { private static boolean val = true; ///① // private static volatile boolean val = true; ///② public static void main(String[] args) { new VolatileTest().new First().start(); new VolatileTest().new Second().start(); } class First extends Thread { @SneakyThrows @Override public void run() { while (true) { if (val) { System.out.println("Thread one is working."+System.currentTimeMillis()); val = false; } } } } class Second extends Thread { @SneakyThrows @Override public void run() { while (true) { if (!val) { System.out.println("Thread two is working."+System.currentTimeMillis()); val = true; } } } } }
private static boolean val = true; 輸出結果如下,某一时刻结果会卡住不在输出,因为线程1、2对val改动结果没有及时刷回主内存,val条件不满足线程1、2运行条件,结果便不再打印
Thread two is working.1660620905273
Thread one is working.1660620905273
Thread two is working.1660620905273
Thread one is working.1660620905273
Thread two is working.1660620905273
Thread one is working.1660620905273
Thread two is working.1660620905273
Thread one is working.1660620905273
Thread two is working.1660620905273
private static volatile boolean val = true; 输出结果如下,线程1、2会持续输出,因为线程1、2分别对val改动对方都可以感知
3581
Thread one is working.1660620633581
Thread two is working.1660620633581
Thread one is working.1660620633581
Thread two is working.1660620633581
Thread one is working.1660620633581
Thread two is working.1660620633581
Thread one is working.1660620633581
Thread two is working.1660620633581
Thread one is working.1660620633581
Thread two is working.1660620633581
Thread one is working.1660620633581
volatile不能保证原子性
public class VolatileAtomicDemo { private volatile static int count=0; private static AtomicInteger sum=new AtomicInteger(0); @SneakyThrows public static void main(String[] args) { for(int i=0;i<500;i++){ Thread thread=new Thread(new Runnable() { @Override public void run() { for(int j=0;j<10000;j++) { count++; sum.incrementAndGet(); } } }); thread.start(); } Thread.sleep(2000); System.out.println("count:"+count); System.out.println("summm:"+sum); } }
输出结果;
count:1792884
summm:5000000
标签:Thread,val,two,volatile,working.1660620905273,线程,小结,working.1660620633581 From: https://www.cnblogs.com/enhance/p/16591047.html