Synchronized底层是如何实现的,锁升级过程

4 篇文章 0 订阅
1 篇文章 0 订阅

首先,其实我们在看博客或者看视频都可以学到这个知识点,但是还是强烈建议大家看书,然后针对某一个不理解的细节去针对性的看博客或者视频。

一、Synchronized作用范围

谷歌翻译是已同步的意思。是Java为了处理并发编程的一个关键字。代表多个线程需要争抢同一把锁,抢到了才能进行自己的工作。在Java中,任何对象都可以用作线程竞争的锁,这也能解释,为什么Object类中有wait,notify等方法了。

可以作用在三个地方:

  • 作用在代码块,需要传入一个锁对象;此时锁住的是传入的对象;
  • 作用在非静态方法上,锁住的是当前类的实例对象;
  • 作用在静态方法上,锁住的是当前类的Class对象。如果自己写工具类,慎重加锁,否则会造成性能问题;

二、jdk1.6之前Synchronized实现

这里为什么要说是jdk1.6之前呢,因为我在学习的时候很容易将实现原理和后边要说的锁升级弄混了,所以我认为分开说比较好。

网上很多写的命令还有啥的都不对,还是自己写吧:编写一个测试类 ,里边有一个synchronized代码块。

package com.lifeisftc.magic.string;

public class LockTest {

        private static Object LOCK = new Object();

        public static int main(String[] args) {
            synchronized (LOCK){
                System.out.println("Hello World");
            }
            return 1;
        }
}

进入到文件目录,先后使用以下命令处理文件,观察命令行输出:

javac LockTest.java
javap -c LockTest

结果如下:注意看红色框,其他的可以不了解

这这俩字节码是啥意思呢?我把JVM书上的解释贴一下:

synchronized关键字经过编译之后,会在同步块的前后分别形成一个monitorentermonitorexit两个 字节码指令。这两个字节码指令都需要一个reference类型的参数来 指明要锁定和解锁的对象。

  • 修饰代码块:取传入对象的reference;
  • 修饰实例方法:取当前实例的reference;
  • 修饰静态方法:取该类Class对象的reference。

在执行monitorenter指令时:

  1. 尝试获取对象锁,如果对象没被锁定,或者当前线程已经拥有了该对象的锁(这种情况是重入),就把锁的计数器+1,特殊情况下重入一次就+1,退出一次就-1。所以最后这个线程释放锁的时候,锁的计数器肯定是0
    1. 这里提一下ReentrantLock,底层源码也有一个volicate修饰的value,用来计数。不过里边有一个判断,最多只能重入Integer.MAX_VALUE次,超过以后就报错了。感兴趣可以看一下。
  2. 那么当有线程抢到锁之后,如何保证其他线程处于阻塞状态,线程执行完后又该怎么唤醒其他线程呢?
    1. 有一点是Java线程是映射到操作系统的原生线程上去的,阻塞和唤醒都需要从用户态切换到内核态,这个时间开销非常大;

Synchronized实现原理讲完了,就这么简单

——————————————————jdk1.6怎么优化Synchronized———————————————

三、锁的优化和升级

刚才说了,实现线程阻塞和唤醒需要从用户态切换到内核态,开销非常大,那到底有多大呢?贴一张JVM书里边的图(1.6之前)

看到了吧,差距就是这么明显,一个关键字被一个API干蒙了,就这?

为了找回场子肯定要优化呀:

附:这部分只是在《深入理解Java虚拟机》第十三章都有写,可以对比着看,我就不复制粘贴了。

既然切换状态花费时间那么长,那我们不切换行不行,用别的方式去实现呢,比如用CAS?

  1. 这样吧,我也不去通知你了,你没抢到锁就自己等一会儿吧,可以原地转个圈(自旋)啥的,转完圈你再来问问我,看看我给不给你;这就是下边要说的自旋锁
  2. 另外还有的人,都不可能会产生线程安全问题的,你也加锁,你加任你加,我编译时候给你去掉,哼!这就是锁消除;
  3. 锁粗化:我们都知道StringBuffer是线程安全的,我要是连着执行三次.append(),那不相当于加了三个锁么,那么在编译时就在开头和结尾加一个不就完了么;
  4. 轻量级锁和偏向锁撤销偏向锁的时候会导致stop the word

偏向锁—>轻量级锁(CAS)—>重量级锁

具体的升级过程参考:https://blog.csdn.net/hbtj_1216/article/details/77161506?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduend~default-1-77161506.nonecase&utm_term=%E8%BD%BB%E9%87%8F%E7%BA%A7%E9%94%81%E8%87%AA%E6%97%8B%E5%A4%9A%E5%B0%91%E6%AC%A1%E5%8D%87%E7%BA%A7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值