谈谈 synchronized和ReenTrantLock 的区别

1.二者都是可重入锁性能

    “可重入锁”概念是:本身能够再次得到本身的内部锁。好比一个线程得到了某个对象的锁,此时这个对象锁尚未释放,当其再次想要得到这个对象的锁的时候仍是能够获取的,若是锁不可重入的话,就会形成死锁。同一个线程每次获取锁,锁的计数器都增1,因此要等到锁的计数器降低为0时才能释放锁。优化

2.synchronized依赖于JVM而ReenTrantLock 依赖于API线程

   synchronized是依赖于JVM实现的,虚拟机团队在JDK1.6为synchronized关键字进行了不少优化,可是这些优化都是在虚拟机层面实现的,并无直接暴露给咱们。ReenTrantLock 是JDK层面实现的(也就是API层面,须要lock()和unlock()方法配合try/finally语句块来完成),因此咱们能够经过查看它的源代码,来看它是如何实现的。对象

3.ReenTrantLock 比synchronized增长了一些高级的功能接口

   相比synchronized,ReenTrantLock 增长了一些高级功能。主要来讲有三点:1.等待可中断  2.可实现公平锁  3.可实现选择性通知(锁能够绑定多个条件)具体以下:虚拟机

        ReenTrantLock 提供了一种可以中断等待锁的线程的机制,经过lock.lockInterruptibly()来实现这个机制。也就是说正在等待的线程能够选择放弃等待,改成处理其余事情。                                                                                                                                                                                                               ReenTrantLock 能够指定是公平锁仍是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先得到锁。ReenTrantLock 默认是非公平锁,也能够经过ReenTrantLock 类的ReentrantLock (boolean fair)构造方法来指定是不是公平的。                                                                             synchronized关键字与wait()和notify/notifyAll()方法结合能够实现等待/通知 机制,ReenTrantLock 类固然能够实现,可是须要借助Condition接口和newCondition()方法。Condition是JDK1.5以后才有的,它具备很好的灵活性,好比能够实现多路通知功能也就是在一个Lock对象中能够建立多个Condition实例(即对象监视器),线程对象能够注册在指定Condition中,从而能够有选择性的进行线程通知,在调度线程上更加灵活。在使用notify/notifyAll()方法进行通知时,被通知的线程是由JVM选择的,用 ReenTrantLock 类结合Condition实例能够实现“选择性通知”,这个功能很是重要,并且是Condition接口默认提供的。而synchronized关键字就至关于整个Lock对象中只有一个Condition实例,全部的线程注册都在它一个身上。若是执行notifyAll方法的话就会通知全部处于等待状态的线程,这样会形成很大的效率问题,而Condition实例的signalAll()方法只会唤醒注册在该Condition实例中的全部等待线程。it

4.性能已不是选择标准                                                                        io

相关文章
相关标签/搜索