并发锁

1、乐观锁与悲观锁

  悲观锁:假设一定会发生问题,所以要进行加锁。

  乐观锁:假设不会发生问题,边运行边检测冲突,发生冲突采取补偿措施,一般是不断重试。(CAS)

乐观锁适用于发生冲突频率不高的情况,悲观锁适用于发生冲突频率高情况(使用乐观锁就会不断重试开销很大)

2、公平锁与非公平锁

  公平锁:多线程在等待同一把锁时,必须按照先来先得的顺序获得锁

  非公平锁:线程争用,谁抢到就是谁的。

  公平锁的性能比非公平锁差一些,但是公平锁不会出现线程饥饿现象。

  一般默认都是非公平锁,可以设置成公平锁。

3、读写锁

  读锁:共享锁,可以同时被多个读线程获取。

  写锁:独占锁,只能被一个写线程获取。

4、虚拟机对的锁优化

  锁消除:消除不必要的锁。

  锁粗化:在一定范围内频繁加锁解锁,就可以扩大锁的粒度。

  自旋锁:在锁被占用时,先让线程自旋(忙等待)而不是阻塞,超过了等待限度再阻塞。

  自适应自旋锁:如果上一次成功获得过锁则会延长自旋时间,如果很少获得过锁则可能直接阻塞。

  PS:阻塞是一个很重的操作,系统调用、上下文切换、cup从用户态切换到内核态。

  偏向锁(CAS)、轻量级锁(CAS)、重量级锁(加锁阻塞)的关系。

  偏向锁遇到锁争用会升级为轻量级锁,轻量级遇到多个线程争用膨胀为重量级锁。

5、AQS

  AQS:是JUC包中的抽象类,锁大部分公共方法都由此类实现,且不准子类覆盖。

  使用模板方法设计模式提供tryAcquire()、tryRelease()、tryAcquireShared()、tryReleaseShared()和钩子等供程序员自定义锁。

  其原理是CAS+阻塞原语,以ReentrantLock举例,获得锁CAS操作使得state+1,多次获得state+n,其他线程park()进入阻塞队列,直到state=0,抢占锁。

posted @ 2020-03-15 22:17  卑微芒果  Views(519)  Comments(0Edit  收藏  举报