在谈Volatile前先回忆一下什么是JMM。
JMM:java内存模型,是java的一种约定,也就是一个概念。为了保证线程安全。线程中分为工作内存和主内存
关于JMM的一些同步的约定:
1.线程释放锁前,必须把共享变量立刻刷回主存。
2.线程加锁时,必须读取主存中的最新值到工作内存中!
3.这锁也是同一把锁。
从一个例子来理解
这个程序会不会停止?
存在的问题是线程程序a不知道主内存的值已经被main线程修改了还在运行就死循环了。
说明线程A不可见主线程的变化。
接下来就能引进Volatile解决不可见性。
如果我们把变量num加Volatile就会停止。验证了可见性。
接下来我们来看看为什么Volatile是非原子性的
通过这段程序可以证明volatile是非原子性的。最终结果num不会是2万。
为什么一行num++的代码也会造成这种情况呢?我们深入底层字节码会发现。
虽然只有一行代码,但是它在底层进行了多步的操作。所以num++不是原子性操作。
如果我们不用synchronized和lock怎么解决这个非原子性的问题呢?
在juc里我们有原子类,可以用它们来解决这个问题。
把num++改成num.getAndIncrement()就可以解决。(底层是CAS)