synchronized使用特性详解,synchronized实现可重入原理

synchronized详解

一、应用
  • 修饰实例方法,锁是实例对象

  • 修饰静态方法,锁就是当前类的 class 对象锁

    • 静态成员不专属于任何一个实例对象,是类成员,因此通过 class 对象锁可以控制静态成员的并发操作。一个线程 A 调用一个实例对象的非 static synchronized 方法,而线程 B 需要调用这个实例对象所属类的静态 synchronized 方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的 class 对象,而访问非静态 synchronized 方法占用的锁是当前实例对象锁,二者的锁并不一样,所以不冲突
  • 修饰代码块,锁对象就是放在括号里面的对象;

    • 锁对象是当前实例

      synchronized(this) {
          for (int j = 0; j < 100; j++) {
              i++;
          }
      }
      
    • 锁对象是类的 class 对象锁

      synchronized(AccountingSync.class) {
          for (int j = 0; j < 100; j++) {
              i++;
          }
      }
      

**在jdk1.6之后,synchronized的内部进行了优化,它不再是一个简单的重量级锁,它为了试用所有的情况,有了一个锁升级流程: 偏向锁 -》 轻量级锁 -》 重量级锁,接下来我们仔细的聊一下所谓的锁升级流程。synchronized是自旋锁 **

重量级锁竞争的时候,还可以使用自旋来进行优化,如果当前线程自旋成功(即这时候持锁线程已经退出了同步块,释放了锁),这时当前线程就可以避免阻塞。 不要立即进行自旋。JVM第四章5.3

二、可重入锁

可重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。(同一个加锁线程自己调用自己不会发生死锁情况)

synchronized 和 ReentrantLock 都是可重入锁。

synchronized的可重入怎么实现

每个锁关联一个线程持有者和一个计数器。当计数器为0时表示该锁没有被任何线程持有,那么任何线程都都可能获得该锁并调用相应方法。当一个线程请求成功后,JVM会记下持有锁的线程,并将计数器计为1。此时其他线程请求该锁,则必须等待。而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,同时计数器会递增。当线程退出一个synchronized方法/块时,计数器会递减,如果计数器为0则释放该锁。

纯手打不易,望点赞支持

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值