volatile和synchronized关键字

173 阅读2分钟

1、基本概念

  • 共享变量可见性 
        多线程操作共享变量时,获取变量的值就是主内存中同步过来最新的值;修改变量时这个值能同步到主内存中去  
  • 操作原子性 
         一个操作或者多个操作要么全部执行完成执行过程不被中断,要么就不执行。即操作不可再分(在汇编层面看为一条机器指令)。比如 a = 1和 retrun a 都是具有原子性 。a+=b则需要分三步完成 
  • 按程序代码顺序执行  
         重排序:代码书写的顺序与实际执行的顺序不同。指令重排序,是编译期或处理器为了提高程序性能而做的优化。 

           as-if-serial语义:无论如何重排序,程序执行的结果应该与代码顺序执行的结果一致(java编译器和处理器都会保证java在单线程下遵循as-if-serial语义)。 

2、volatile 修饰符

      加入内存屏障(又称内存栅栏,是一个CPU指令),既可以保证变量可见性,又可以保证操作的执行顺序,但不能保证操作的原子性  

      对volatile变量执行写操作时,会在写操作后加入一条store屏障指令 对volatile变量执行读操作时,会在读之前加入一条load屏障指令, 把内容同步到主内存中去或者或者把主内存中的内容同步到工作内存中。 

     volatile适用场景:

  • 对变量的写入操作不依赖其当前值
  • 改变量没有包含在具有其他变量的不变式中

3、synchronize 关键字

        可以保证原子性和可见性


4、重入锁(ReentrantLock)

        可以实现可见性和原子性