并发编程中各种锁的介绍

1、乐观锁悲观锁以及它的应用
  • 1、悲观锁

    • 1、悲观锁是一种悲观的并发策略,总是认为只要不去做正确的同步措施(例如加锁),那就会出问题,无论共享数据是否真的会出现竞争,它都要进行加锁。
    • 2、java中利用synchronize的锁属于悲观锁。
  • 2、乐观锁

    • 1、基于冲突检测的乐观并发策略,即先进性操作,如果没有其他线程争用共享数据,那就操作成功了;如果共享数据有争用,那就采用补救措施。
    • 2、这种乐观操作不需要把线程挂起,因此这种同步操作称为非阻塞式同步。
  • 3、乐观锁的两种实现方式

    • 1、版本号时间戳机制
      • 在表中加个version或updatetime字段,在每次更新操作时对此一下该字段,如果一致则更新数据,数据不等则放弃本次修改,根据实际业务需求做相应的处理。
    • 2、CAS方式
      • 即Java中的compareAndSwap。CAS操作涉及到三个操作数,内存值(valueOffSet)、期望值(expect)、更新值(update)。当内存值与期望值一致时就会更新数据,反之不操作。
2、自旋锁
  • 如果机器有两个以上的处理器,能够让两个线程同时并行执行,我们就可以让后面请求锁的那个线程“稍等一下”,但不放弃CPU的执行时间,看看持有锁的线程是否很快就会释放锁。为了让线程等待,我们只需要执行一个忙循环,这就是自旋锁。
  • 自旋锁可以一定程度上减少挂起线程和恢复线程操作带来的性能开销。
3、轻量级锁
  • 1、轻量级锁是为了在没有多线程竞争的前提下(并不是所有时刻都有很多线程同时竞争临界资源),减少传统的重量级锁使用操作系统互斥量产生的性能消耗。
  • 2、当有多个线程同时竞争同一个锁的时候,轻量级锁就不再有效,此时就会膨胀成为重量级锁。后面等待的线程也要进入阻塞状态。
4、偏向锁
  • 1、偏向锁的目的是消除数据在无竞争情况下的同步原语。
  • 2、偏向锁的意思是,这个锁会偏向第一个获得它的线程,如果在接下来的执行过程中,该锁没有被其他线程获取,则持有该锁的线程将永远不需要进行同步。
  • 3、当有另外一个线程尝试去获取这个锁时,偏向模式就会宣告失败。
5、锁的升级、降级
  • 锁的升级、降级,就是JVM优化synchronized运行的机制,当JVM检测到不同的竞态的时候,会自动切换到合适的锁实现。
    • 当检测到没有竞争出现的时候,默认会使用偏向锁,以表示对象偏向于当前线程,所以不涉及真正的互斥。这种情形基于,大部分对象 生命周期内最多会被一个线程锁定,使用偏向锁可以降低竞争开销。
    • 如果另外的线程试图锁定某个已经被偏向过的对象,之前的偏向锁就会失效,切换到轻量级锁,如果重试成功,就使用普通轻量级锁,否侧进一步升级为重量级锁。

你可能感兴趣的:(个人,技术,笔记)