原子性和可见性

简单的说就是:
  原子性,不被线程调度器中断的操作,同一时间只有一个线程进行操作。当线程要操作被synchronized修饰的内存或操作时,必须首先获得锁才能进行后续操作;但是在同一时刻只能有一个线程获得相同的一把锁,保证了线程安全,相当于将非原子性操作转化为了原子性。

  可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的,操作状态多线程之间互相可见。volatile让变量每次在使用的时候,都从主存中取。而不是从各个线程的“工作内存”。volatile具有synchronized关键字的“可见性”,但是没有synchronized关键字的“并发正确性”,也就是说不保证线程执行的有序性。volatile变量对于每次使用,线程都能得到当前volatile变量的最新值,但是volatile变量并不保证并发的正确性。
举个简单的例子:
  多线程并发操作count++,

cup的执行过程是:
1.将count值从内存加载到cup的寄存器A(备份过程);
2.将A中的count值+1(计算),将A中的count计算结果值存放到寄存器B(缓存区);
3.在某些“恰当的”时刻,cup将寄存器B中的count值写回到内存
(注:这样做的好处是减少对内存的读取,提高执行效率)
那么,并发状态下,count值在A中的计算结果在写入内存之前,止步于缓存区状态,各线程之间不能获取其他线程的操作结果,这是不可见性。
  关键字volatile修饰count,执行上述操作:
1.将count值从内存加载到cup的寄存器A(备份过程);
2.将A中的count值+1(计算),将A中的count计算结果值存放到寄存器B(缓存区);
3.将寄存器中的count值写回到内存(同步执行)。
count值在A中的计算结果同时写入缓存区和内存中,各线程之间能获取其他线程的操作结果,这是可见性。
  但是这种情况,依然存在线程安全问题,多线程并发操作获取内存中的count值可能相同(计算结果还未写入内存),多线程同时执行计算,即使计算多次,依然相当于就算了一次,这是非原子性。
简单总结:
synchronized保证了原子性和可见性
volatile仅仅保证了可见性
那么什么时候会使用volatile,看到某个精髓的总结是:一写多读。就是说,单个线程进行写操作,其他多个线程进行读操作。单个线程写能及时将最新的数据写至主内存,多个线程读的时候能保证主内存中数据一定是最新的。