• 经典面试题-lock与synchronized异同点


    lock vs synchronized

    • 语法层面
      • synchronized 是java关键字,源码在 jvm 中,也被成为java中的内置锁,用 c++ 语言实现
      • Lock 是接口,源码由 jdk 提供,用 java 语言实现
      • 使用 synchronized 时,退出同步代码块锁会自动释放,而使用 Lock 时,需要手动调用 unlock 方法释放锁(可以写try…finally…中释放锁)
    • 功能层面
      • 二者均属于悲观锁、都具备基本的互斥、同步、锁重入功能

        互斥:多个线程争抢同一把锁,只有一个线程能够成功
        同步:多个线程同时运行,当一个线程运行到某一行代码时,发现需要其他线程的结果,此时该线程就不能继续向下运行了,需要等待其他线程的结果,才能继续向下执行(synchronized可以通过wait,notify实现同步;lock 可以使用条件变量condition.await()释放锁(释放锁之后就进入了等待队列);condition.single()唤醒 (唤醒之后还是会到blocked queue来排队) 来实现同步)
        锁重入:持锁的线程能不能继续加第二道锁第三道锁,如果可以则是可重入锁(synchronized,lock 都是可重入锁,对同一个对象加多道锁)

      • Lock 提供了许多 synchronized 不具备的功能,例如获取等待状态、公平锁、可打断、可超时、多条件变量

        获取等待状态:比如互斥,一个线程获取到锁,其他线程阻塞,此时想知道那些线程被阻塞住了,synchronized 就不行,但是lock就可以;在比如同步时,有多个线程已经在对象上调用了wait()在等等,想知道该对象上有哪些线程在等待,synchronized 就不行,但是lock就可以;
        公平锁:多个线程争抢锁,失败的线程在次是先来先得还是允许别插队呢,先来先得则为公平锁,允许插队则是非公平锁;synchronized 只支持非公平锁(并不是根据锁后给等待的线程分配锁的。每次锁被释放后,任何一个线程都有机会竞争到锁。目的就是为了提高执行性能,当然缺点是有可能会产生线程饥饿。)Lock 即支持公平锁又支持非公平锁;公平锁的吞吐量上并不如非公平锁高,一般推荐非公平锁
        可打断:有一个持锁线程,我的线程想获取锁时,如果是lock则可以打断;synchronized 不支持打断
        可超时:lock支持设置超时时间,如果超时则放弃锁的获取;synchronized 不支持超时
        多条件变量:synchronized只有一个等待队列,lock有多个等待队列

      • Lock 有适合不同场景的实现,如 ReentrantLock(可重入锁), ReentrantReadWriteLock(适合读多写少的)
    • 性能层面
      • 在没有竞争时,synchronized 做了很多优化,如偏向锁、轻量级锁,性能不赖在
      • 竞争激烈时,Lock 的实现通常会提供更好的性能
    TestReentrantLock类中打印的
    
    | Lock ----------------------|
    | owner[null] state[0]       |
    | blocked queue              |
    | waiting queue [c1]         |
    | waiting queue [c2]         |
    |----------------------------|
    owner:代表锁的持有者,null表示没有线程持有这把锁,state代表加锁状态,0表示没有人对他加锁,如果有人加锁则加1
    blocked queue:如果获取锁失败则进入队列等待;双向链表
    waiting queue [c1]:当前线程获取锁之后条件不满足,则先把锁释放开,将锁给别人用,当前线程需要在waiting queue中等待;LOCK.newCondition("c1");来创建waiting queue;单向链表
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 条件变量
      ReentrantLock 中的条件变量功能类似于普通 synchronized 的 wait,notify,用在当线程获得锁后,发现条件不满足时,临时等待的链表结构
      与 synchronized 的等待集合不同之处在于,ReentrantLock 中的条件变量可以有多个,可以实现更精细的等待、唤醒控制
  • 相关阅读:
    C++ Reference: Standard C++ Library reference: C Library: cwchar: ungetwc
    【Mycat】Mycat主从复制
    springboot+vue农产品销售配送网站
    linux操作系统中的动静态库(未完)
    嵌入式系统开发笔记107:层次化软件设计思想
    《码处高效:Java开发手册》之代码风格
    Kotlin版本实现Gradle插件
    Linux内存管理(十六):buddy 系统分配器之页面释放
    C语言家政服务系统
    计算机专业的学生需要每天刷题吗?
  • 原文地址:https://blog.csdn.net/xiaoshiguang3/article/details/125884487