Java中的那些‘锁‘事

synchronized


        synchronized中文意思是'同步',在java代码中也被称为同步锁。它的作用是保证同一时刻只有一个线程执行被synchronized修饰的代码块或方法,从而实现我们常说的'线程安全'。

        synchronizd使用方法主要分为3种:

  1. 修饰实例方法
  2. 修饰静态方法
  3. 修饰代码块

        具体使用规则大家可以百度,这里就不在赘述了。

        那么synchronized底层原理是什么呢?

        其实synchronized是通过monitor对象监视器来实现的,对于monitor对象监视器,大家可以把它理解为对与一个对象当前锁状态的监控,多个线程执行同一个同步代码块时,其实就是在争夺这个对象的monitor,如果大家尝试反编译我们synchronized的代码就会发现,在同步代码块开始时有monitorenter,结束时有monitorexit  的代码执行,这两个执行就是为了获取monitor和释放monitor。

public class com.test.testSyn.Main { 
  public static final java.lang.Object object; 
 
  public com.yang.testSyn.Main(); 
    Code: 
       0: aload_0 
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V 
       4: return 
 
  public void print(); 
    Code: 
       0: getstatic     #2                  // Field object:Ljava/lang/Object; 
       3: dup 
       4: astore_1 
       5: monitorenter 
       6: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream; 
       9: ldc           #4                  // String 123 
      11: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
      14: aload_1 
      15: monitorexit 
      16: goto          24 
      19: astore_2 
      20: aload_1 
      21: monitorexit 
      22: aload_2 
      23: athrow 
      24: return 
    Exception table: 
       from    to  target type 
           6    16    19   any 
          19    22    19   any 
 
  static {}; 
    Code: 
       0: new           #6                  // class java/lang/Object 
       3: dup 
       4: invokespecial #1                  // Method java/lang/Object."<init>":()V 
       7: putstatic     #2                  // Field object:Ljava/lang/Object; 
      10: return 
} 

偏向锁:后来java开发人员发现对于同步代码其实大部分情况下不存在多个线程争夺锁的情况,一般都是同一个线程执行这段同步代码块,此时每次还要在获取锁、释放锁,对于性能的消耗是很大的,所以对于只有一个线程获取锁时,只有该线程第一次获取锁会加锁(cas操作),后续就不需要加锁可以直接执行,这种就叫偏向锁。

轻量级锁:如果偏向锁在线程1执行完后,又有线程2来执行这段代码,线程2此时只需要执行加锁操作,如果线程1还没有执行完,线程2会通过自旋等待其实现完再加锁,这就是轻量级锁

重量级锁:在轻量级的基础上,此时如果又有1个或多个线程来竞争该锁,那么所有试图获取该锁的线程都会被阻塞,直到锁释放 唤醒这些线程。这就是重量级锁。


AQS

        AQS:全称是 AbstractQueuedSynchronizer,中文译为抽象队列式同步器。

        AQS的实现原理:AQS内部保存有state的变量,每个线程在抢锁的时其实就是取修改state的值,如果修改成功了,那么该线程就获取到锁,反之就没有获取到锁,进入阻塞队列等待。

        AQS修改state是通过java中Unsafe类中的compareAndSwap方法实现的,该方法的作用就是保证操作的原子性,其参数一共有4个:操作对象、原始值、偏移量、变更后的值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值