zoukankan      html  css  js  c++  java
  • synchronized和ReentrantLock

    相同之处

    都是阻塞式的同步,也就是说当如果一个线程获得了对象锁,进入了同步块,其他访问该同步块的线程都必须阻塞在同步块外面等待,而进行线程阻塞和唤醒的代价是比较高的(操作系统需要在用户态与内核态之间来回切换,代价很高,不过可以通过对锁优化进行改善)。

    不同之处

    实现层次

    这两种方式最大区别就是对于Synchronized来说,它是java语言的关键字,是原生语法层面的互斥,需要jvm实现。而ReentrantLock它是JDK 1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配合try/finally语句块来完成。

    锁的获取

    synchronized:假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待。

    ReentrantLock 获取锁的方式更加灵活
        a)  lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁。

        b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false。

        c)tryLock(long timeout,TimeUnit unit),   如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁,就返回true,如果等待超时,返回false。

        d) lockInterruptibly:如果获取了锁立即返回,如果没有获取锁,当前线程处于休眠状态,直到或者获取锁,或者当前线程被别的线程中断。

    锁的释放

    synchronized:自动释放锁,同步块代码执行完毕或出现异常。

    ReentrantLock :finally块中释放锁

    相比于synchronized,ReentrantLock增加了一些高级功能。

    等待可中断

    等待可中断是指持有锁的线程长期不释放的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。

    公平锁

    公平锁是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序获得锁。非公平锁无法保证这一点,在锁被释放时,任何一个等待的线程都有机会获得锁。

    synchronized中的锁是非公平锁,ReentrantLock默认是非公平锁,可以通过构造函数的布尔参数设为公平锁。

    绑定多个条件

    一个ReentrantLock对象可以同时绑定多个Condition对象,而在synchronized中,锁对象的wait()和notify()或notifyAll()方法可以实现一个隐含的条件,如果要和多余一个条件关联的时候,就不得不额外地添加一个锁,而ReentrantLock则无须这么做,只需要多次调用new Condition()方法即可。

    总结如下

    类别

    synchronized

    Lock

    存在层次

    Java的关键字,在jvm层面上

    是一个类,API层面

    锁的释放

    执行完同步块代码,释放锁

    执行同步块代码发生异常,释放锁

    在finally中释放锁

    锁的获取

    假设A线程获得锁,B线程等待。

    如果A线程阻塞,B线程会一直等待

    Lock有多个锁获取的方式

    锁状态

    无法判断

    可以判断

    锁类型

    可重入 不可中断 非公平

    可重入 可中断 可公平

  • 相关阅读:
    t
    0409笔记
    vue typescript ui库
    0329
    express+sequelize 做后台
    android申请多个权限的正确姿势
    [BBS] Reply.jsp 03
    [BBS] ShowArticleDetail.jsp 02
    [BBS] ShowArticleTree.jsp 01 帖子的树形展现-递归 、Session 存 login 否
    [Jweb] MyEclipse 的常见操作
  • 原文地址:https://www.cnblogs.com/deltadeblog/p/9564719.html
Copyright © 2011-2022 走看看