Java并发编程第一记——volatile与synchronized

1. volatile

允许共享变量,它保证每一个线程看到变量的值都是一致的,是轻量级的synchronized。其实现原理是CPU的LOCK指令,这个指令会做两件事:将当前处理器中的缓存行(缓存最小分配单位)回写到内存中和使其它处理器的缓存行失效。

2. synchronized

通过锁的方式来实现同步。Java里面有三种锁:偏向锁、轻量级锁、重量级锁(级别依次升高)。当访问同步块时必须获得锁,锁的信息存储在Java对象头中。

  • 偏向锁:最低级别的锁,jvm默认开启。这个锁为了解决以下这个问题:当一个同步块,本身竞争不是很多,被一个线程反反复复的使用,那么这个线程将会每次都会通过CAS(比较再交换)来获得锁,同步块也会每次都加锁。这个开销是很大的,为了解决这个现象,引入了偏向锁——即记录线程ID,如果有偏向锁,且指向的是正要访问的线程的ID,那么将不会解锁,而是直接获得访问权限,之后也不会频繁解锁,大大减少开支。
  • 轻量级锁:简单点说,就是不会阻塞线程,而是会进行自旋操作,多次尝试获得锁。经过多次尝试之后,便会升级成重量级锁,阻塞线程,注意升级之后不会降级。自旋操作会消耗CPU资源,但是,有了自旋会大大提高线程的响应时间。
  • 重量级锁:没有锁的线程,会等待其它线程释放锁才能继续进行,最高级别的锁。

3. 补充

  • 原子操作:不可中断的一个或一系列动作或指令。CPU实现原子操作是加锁,总线上锁或者缓存行上锁。
  • CAS:比较再交换,当前值没有发生变化,如果旧值发生变化,不更新新值,否则更新。旧值变化,说明已经修改了,保证同步,不更新成新值。
  • Java使用锁和循环 CAS来实现原子操作。除了偏向锁,其它Java实现同步都使用了循环CAS,但是其循环开销大,ABA问题和只能保证一个一个变量的问题还是有的。

你可能感兴趣的:(学习总结,java,多线程,并发编程)