Java高级特性系列--锁机制

《Java高级特性系列--锁机制》

 

Lock与ReentrantLock

尽管synchronized在语法上已经足够简单了,在JDK 5之前只能借助此实现,但是由于是独占锁,性能却不高,因此JDK 5以后就开始借助于JNI来完成更高级的锁实现。JDK 5中的锁是接口java.util.concurrent.locks.Lock。另外java.util.concurrent.locks.ReadWriteLock提供了一对可供读写并发的锁。根据前面的规则,我们从java.util.concurrent.locks.Lock的API开始。

void lock();

获取锁。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态。

void lockInterruptibly() throws InterruptedException;

如果当前线程未被中断,则获取锁。

如果锁可用,则获取锁,并立即返回。

如果锁不可用,出于线程调度目的,将禁用当前线程,并且在发生以下两种情况之一以前,该线程将一直处于休眠状态:

  • 锁由当前线程获得;或者
  • 其他某个线程中断当前线程,并且支持对锁获取的中断。

如果当前线程:在进入此方法时已经设置了该线程的中断状态;或者在获取锁时被中断,并且支持对锁获取的中断,则将抛出 InterruptedException,并清除当前线程的已中断状态。

Condition newCondition();

返回绑定到此 Lock 实例的新 Condition 实例。下一小节中会重点谈Condition,此处不做过多的介绍。

boolean tryLock();

仅在调用时锁为空闲状态才获取该锁。如果锁可用,则获取锁,并立即返回值 true。如果锁不可用,则此方法将立即返回值false。通常对于那些不是必须获取锁的操作可能有用。

boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。

如果锁可用,则此方法将立即返回值 true。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在发生以下三种情况之一前,该线程将一直处于休眠状态:

  • 锁由当前线程获得;或者
  • 其他某个线程中断当前线程,并且支持对锁获取的中断;或者
  • 已超过指定的等待时间

如果获得了锁,则返回值 true

如果当前线程:在进入此方法时已经设置了该线程的中断状态;或者在获取锁时被中断,并且支持对锁获取的中断,则将抛出 InterruptedException,并会清除当前线程的已中断状态。

如果超过了指定的等待时间,则将返回值 false。如果 time 小于等于 0,该方法将完全不等待。

void unlock();

释放锁。对应于lock()、tryLock()、tryLock(xx)、lockInterruptibly()等操作,如果成功的话应该对应着一个unlock(),这样可以避免死锁或者资源浪费。

示例如下:

public class AtomicIntegerWithLock { private int value; private Lock lock = new ReentrantLock(); public AtomicIntegerWithLock() { super(); } public AtomicIntegerWithLock(int value) { this.value = value; } public final int getAndSet(int newValue) { lock.lock(); try { int ret = value; value = newValue; return ret; } finally { lock.unlock(); } } public final boolean compareAndSet(int expect, int update) { lock.lock(); try { if (value == expect) { value = update; return true; } return false; } finally { lock.unlock(); } } public final int getAndIncrement() { lock.lock(); try { return value++; } finally { lock.unlock(); } } } 

理论上说Lock的性能比synchronized的要好得多。如果可以的话总是使用Lock替代synchronized是一个明智的选择。但是,随着JVM的发展和优化,synchronized与Lock几乎没有差别了。

 

    原文作者:java锁
    原文地址: https://www.cnblogs.com/IvySue/p/7481419.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞