首页   快速返回

Java锁机制     所属分类 java
悲观锁 乐观锁 
自旋锁 适应性自旋锁
偏向锁 轻量级锁 重量级锁
公平锁 非公平锁
可重入锁 非可重入锁
共享锁 排他锁

是否要锁住同步资源 锁住 悲观锁  不锁住 乐观锁
锁住同步资源失败,是否需要阻塞  阻塞  不阻塞 自旋 适应性自旋
多个线程竞争锁是否需要排队  排队 公平锁  不排队 非公平锁
是否可以多次获取同一把锁  可以 可重入锁  不可以 不可重入锁
是否可以共享同一把锁 可以 共享锁  不可以  排他锁


Java中ReentrantLock和synchronized都是可重入锁,可重入锁的一个优点是可一定程度避免死锁

ReentrantReadWriteLock  读锁 写锁

synchronized关键字和Lock的实现类都是悲观锁
java.util.concurrent.atomic  基于CAS实现的乐观锁

悲观锁适合写操作多的场景
乐观锁适合读操作多的场景

乐观锁缺点
1 ABA问题  
  J.U.C 提供 AtomicStampedReference 通过控制变量值的版本来保证 CAS 的正确性
2 自旋时间长开销大 
  如果JVM能支持处理器提供的pause指令那么效率会有一定的提升,pause指令有两个作用, 
  第一它可以延迟流水线执行指令(de-pipeline),使CPU不会消耗过多的执行资源, 延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零。 
  第二它可以避免在退出循环的时候因内存顺序冲突(memory order violation) 而引起CPU流水线被清空(CPU pipeline flush),从而提高CPU的执行效率。 

3 只能保证一个共享变量的原子操作
  AtomicReference 保证引用对象之间的原子性  , 可以把多个变量封装成对象里来进行 CAS 操作
  
  
自旋锁优缺点
优点
阻塞或唤醒一个 Java 线程需要操作系统切换 CPU 状态来完成,这种状态转换需要耗费处理器时间。
如果同步代码块中的内容过于简单,状态转换消耗的时间有可能比用户代码执行的时间还要长。
所以自旋锁就可以避免 CPU 切换带来的性能、时间等影响。

缺点
自旋等待虽然避免了线程切换的开销,但它要占用处理器时间。
如果锁被占用的时间很短,自旋等待的效果就会非常好。
反之,如果锁被占用的时间很长,那么自旋的线程只会白浪费处理器资源。
所以,自旋等待的时间必须要有一定的限度,如果自旋超过了限定次数(默认是 10 次,可以使用 -XX:PreBlockSpin 来更改)没有成功获得锁,就应当挂起线程


无锁 偏向锁 轻量级锁 重量级锁

当锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁,其他线程通过自旋的形式尝试获取锁,不会阻塞,从而提高性能


 
公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得
非公平锁(Nonfair):加锁时不考虑排队等待问题,直接尝试获取锁,如果的锁的状态可用,那么该线程会跳过所有等待直接获取锁,相当于有插队行为

ReentrantLock 默认 非公平锁
public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
}
    
公平锁有个!hasQueuedPredecessors()条件

当前同步队列没有前驱节点(也就是没有线程在等待)时才会去compareAndSetState(0, acquires) 使用CAS修改同步状态变量,
根据线程发出请求的顺序获取锁

  
非公平锁的实现在刚进入lock方法时会直接使用一次CAS去尝试获取锁,不成功才会到acquire方法,
而在nonfairTryAcquire方法中并没有判断是否有前驱节点在等待,直接CAS尝试获取锁


 MySQL锁机制 

上一篇     下一篇
规则引擎easyrules

Mysql锁机制

mysql连接信息查看

java资源加载方式比较

java number 比较陷阱

手机4G信号突然变成2G信号