Lock锁和AQS

java 的锁分为两类:

  • 第一类是 synchronized 同步关键字,这个关键字属于隐式的锁,是 jvm 层面实现,使用的时候看不见;
  • 第二类是在 jdk5 后增加的 Lock 接口以及对应的各种实现类,这属于显式的锁,就是我们能在代码层面看到锁这个对象,而这些个对象的方法实现,大都是直接依赖 CPU 指令的,无关 jvm 的实现。

在这里插入图片描述

synchronized 原理

  • 修饰对象 对象锁
  • 修饰类 类锁
  • 修饰方法 实例方法 对象锁 静态方法 类锁
原理
修饰方法 - 依靠ACC_SYNCONSIZED标志

在执行一个方法之前,首先会识别ACC_SYNCONSIZED位,如果有,表明是一个同步方法,执行方法之前必须获取对象的Monitor,才会进去执行方法一当中内容,并且执行结束之前,其他线程无法获取当前Monitor,直到方法结束或者抛出异常。

public class Tues {
    public static int i ;
    public synchronized static void syncTask(){
        i++;
    }
}

例子

修饰代码快 - 依赖指令 MONITORENTER 和 MONITOREXIT 指令
public class Test {
    public static int i ;
    public  static void syncTask(){
        synchronized (Test.class){
            i++;
        }
    }
}

字节码: 注意其中的两个指令 MONITORENTER 和 MONITOREXIT 指令

  public static syncTask()V
    TRYCATCHBLOCK L0 L1 L2 null
    TRYCATCHBLOCK L2 L3 L2 null
   L4
    LINENUMBER 12 L4
    LDC Lcom/ll/payconter/intf/entity/Test;.class
    DUP
    ASTORE 0
    MONITORENTER
   L0
    LINENUMBER 13 L0
    GETSTATIC com/ll/payconter/intf/entity/Test.i : I
    ICONST_1
    IADD
    PUTSTATIC com/ll/payconter/intf/entity/Test.i : I
   L5
    LINENUMBER 14 L5
    ALOAD 0
    MONITOREXIT
   L1
    GOTO L6
   L2
   FRAME FULL [java/lang/Object] [java/lang/Throwable]
    ASTORE 1
    ALOAD 0
    MONITOREXIT
   L3
    ALOAD 1
    ATHROW
   L6
    LINENUMBER 15 L6
   FRAME CHOP 1
    RETURN
    MAXSTACK = 2
    MAXLOCALS = 2
}

Lock锁 原理

Lock 完全用 Java 写成,在java这个层面是无关JVM实现的。虽然 Lock 缺少了 (通过 synchronized 块或者方法所提供的) 隐式获取释放锁的便捷性,但是却拥有了锁获取与释放的可操作性、可中断的获取锁以及超时获取锁等多种 synchronized 关键字所不具备的同步特性。
锁的原理,主要是依靠聚合了一个同步器(AbstractQueuedSynchronizer 缩写为 AQS)的子类来完成线程访问控制的。
比如常见的ReentrantLock,其中内聚了Sync ,实现了AbstractQueuedSynchronizer进行线程的同步管理

 abstract static class Sync extends AbstractQueuedSynchronizer
AQS 怎么进行管理线程访问呢

AQS原理是:如果一个共享资源是处于空闲状态,就标记当前线程为访问线程,如果当前资源处于非空闲状态,就需要一个一个线程阻塞等待以及唤醒资源分配机制,AQS通过int类型变量表示状态,使用一个FIFO的队列进行线程管理,使用CAS进行状态改变。

什么事CAS

什么是 CAS? CAS 即比较并替换(Compare And Swap)。CAS 操作包含三个操作数——内存位置、预期原值及新值。执行 CAS 操作的时候,将内存位置的值与预期原值比较,如果相匹配,那么处理器会自动将该位置值更新为新值,否则,处理器不做任何操作。

Lock锁就是需要AbstractQueuedSynchronizer子类进行实现

 /** Synchronizer providing all implementation mechanics */
    private final Sync sync;  手动设置公平锁或者非公平锁


/**
     * Creates an instance of {@code ReentrantLock}.
     * This is equivalent to using {@code ReentrantLock(false)}.
     */
    public ReentrantLock() {
        sync = new NonfairSync();  默认是非公平锁
    }

ReentrantLock的三个实现
参考链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值