JAVA基础: synchronized 和 lock的区别、synchronized锁机制与升级

1 synchronized 和 lock的区别

  1. synchronized是一个关键字, lock是一个接口,实际使用的是实现类

  2. synchronized通过触发的是系统级别的锁机制, lock是API级别的锁机制

    synchronized自动获得锁,自动释放锁。 lock需要通过方法获得锁并释放锁

  3. synchronized可以修饰代码段和方法,lock只能修饰代码中

  4. synchronized无法判断是否获得锁,lock可以通过tryLock判断

  5. synchronized一旦阻塞无法中断,lock可以被中断 lock.lockInterruptibly();等待并可以被中断

  6. synchronized一旦出现死锁无法自动解决,lock出现死锁后自动解除

  7. synchronized锁的形式单一, lock锁的形式多样化(可重入锁,排他锁,共享锁,读写锁,公平锁,非公平锁)

  8. synchronized早先属于重量级锁,性能较低。 lock相比之下性能略高

main(){
    A a = new A();
    //问题是:在线程1调用t1方法,睡眠的10秒中,线程2和线程3和线程4能否执行?
    new Thread(()->{a.t1()});
    new Thread(()->{a.t2()});
    new Thread(()->{a.t3()});
    new Thread(()->{a.t4()});
    new Thread(()->{a.t5()});
}

class A{
    public synchronized void t1(){ //睡眠了10s中 }
    public synchronized void t2(){}
    public void t3(){}
    public synchronized static void t4(){} //静态方法,属于类(模板对象 Class)
    public void t5(){
        synchronized(this.getClass()){}
    }    
}

2 synchronized详解

2.1 用户态与内核态

  • 可以理解成是两种对系统元件不同的访问权限

  • 程序运行时,会用到很多系统的元件。

  • 不是所有的元件,所有的程序都具有使用权限

  • 有些元件普通程序(Java程序)就可以直接访问,此时我们就说程序处于用户态

  • 有些元件普通不能直接访问,需要通过系统帮助访问(CPU, IO等),此时我们就说程序处于内核态

  • 我们的在运行的过程中,随着需要使用的系统元件不同,有可能会从用户态切换到内核态

  • 用户态与内核态的切换需要耗时,耗资源。

2.2 用户线程 与 内核线程

  • 系统有自己的线程,称为内核线程

  • 我们使用Java语言创建的线程(Thread),称为用户线程

  • 内核线程的数量与系统的cpu数量(逻辑处理器数量)是相同

  • 用户线程在执行过程中,不是直接抢占CPU,而是要争抢与内核线程的关联(映射)

  • 如果创建的用户线程过多, 多个用户线程会映射到一个内核线程上

  • 但一个内核线程每次(一个时间片)只能为一个用户线程执行任务

  • 所以当内核线程在多个用户线程之间切换时,需要保留上一个线程执行的相关信息

  • 我们称这个过程为上下文切换

  • 上下文切换耗时,耗资源

2.3 synchronized重量级锁

  • synchronized在上锁时,最终使用的是系统级别的mutex互斥锁(排他锁)

  • 使用synchronized上锁时,会存在用户态与内核态的切换,性能较低。

  • 我们称这种会涉及到系统资源使用的锁,为重量级锁。

  • jdk1.5 推出JUC之后, lock锁在一定程度上,减缓了重量级的性能消耗

  • lock锁在整个锁应用过程中,有一部分是在用户态完成的,少量在内核态完成。

  • 所以lock在整体性能上要优于synchronized锁。

2.4 synchronized锁升级

  • 早先版本(1.6-) , synchronized属于重量级锁,因为他直接使用系统级别的互斥锁

  • 所以1.5版本的juc中,lock对于synchronized有所优化

  • 1.6 直接对synchronized做了优化 , 提供了锁升级的机制

  • 升级过程

  • 注意:无论锁怎么样升级降级,对我们的编码没有影响。

  • 可以利用JOL工具 和 对对象头结构的理解来测试锁升级的过程

  • 创建对象时,在jvm堆内存中会开辟存储空间。这个对象空间也有一定的结构

    • 部分一: 对象头

      1. mark word 标记内容 ,其中包括锁标记,随着锁升级,锁标记也会变化

      2. Klass 指向类模板

    • 部分二: 属性数据空间

    • 部分三: 数据对齐

    • 扩展:如果是数组对象,还有部分四,length属性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值