本文参考自:https://blog.51cto.com/u_15651175/5545001
什么是Lock接口
Lock接口是JDK1.5提供的一个锁接口,让程序员可以更灵活地实现锁或者可以使用JDK自带的实现Lock接口的一些锁。与Synchronized相比,Lock接口是显式获取、释放锁,交由程序员去控制什么时候获取和释放锁,除此之外还增加了很多特性,比如非阻塞性获取锁,非阻塞超时获取锁,可响应中断获取锁,自定义阻塞条件等。而Synchronized是重量级锁,获取和释放锁都是隐式的,是JVM来实现的;那是不是Lock接口就比Synchronized性能高很多呢,在JDK1.5之前确实是这样,但是在JDK1.5之后,对Synchronized进行了优化,有了锁升级的概念,偏向锁-自旋锁-重量级锁,具体的锁升级过程我就不详细展开了,有兴趣的话可以自行去了解下。我的理解是,Lock接口更灵活,能满足不同需求,解决不同情形下的问题。
JDK提供的Lock接口
/** * 阻塞性地获取锁 */ @Override public void lock() { } /** * 能够相应中断地获取锁 * @throws InterruptedException */ @Override public void lockInterruptibly() throws InterruptedException { } /** * 非阻塞性地获取锁 * @return */ @Override public boolean tryLock() { return false; } /** * 非阻塞性地超时获取锁 * @param time * @param unit * @return * @throws InterruptedException */ @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return false; } /** * 释放锁 */ @Override public void unlock() { } /** * 定义阻塞条件 * @return */ @Override public Condition newCondition() { return null; }
1.lock(),获取锁,如果锁内其他线程获取则进行等待,需要和unlock方法配合主动释放锁。发生异常时,不会主动释放锁,所以释放锁的操作放在finally块中
2.lockInterruptibly()方法,当通过这个方法去获取锁时,如果线程正在等待获取锁,则这个线程能响应中断,即中断线程的等待状态。也就是说,当两个线程同时通过ock.lockInterruptibly()想获取某个锁时,假如线程A获取到了锁,线程B等待,那么对线程B调用threadB.interrupt()方法能够中断线程B
的等待过程
3.tryLock方法,用来尝试获取锁,会立即返回,不管是否成功获取锁
4.tryLock(long time, TimeUnit unit)方法,非阻塞超时获取锁,如果获取到锁,则立即返回,否则继续获取锁,一旦超过指定时间还未成功,就会返回
5.Condition可以配合锁使用,类似于wait()/notify()/notifyAll()这种等待通知模型,等价于await()/signal()
总结
1.ReentrantLock支持非阻塞性地获取锁、可响应中断,而Synchronized不行
2.ReentrantLock显示获取和释放锁,而Synchronized是隐式获取和释放锁,是通过JVM实现的
3.ReentrantLock可以支持公平锁和非公平锁(非公平锁会马上去竞争锁,如果不成功则会返回到阻塞队列,而公平锁则是先去阻塞队列等待),而Synchronizred是非公平锁
4.Synchronized在发生异常的时候会自动释放锁,而ReentrantLock发生异常时,不会自动释放锁,所以一般要用try/finally包起来,在finally释放锁
5.Synchronized和ReentrantLock都是可重入锁
标签:释放,return,Synchronized,区别,Lock,获取,线程 From: https://www.cnblogs.com/mojianheng/p/17439638.html