Lock锁—lock方法源码分析(锁获取)

Lock锁是jdk1.5中引入的java线程安全与同步机制。

java.util.concurrent.locks包下常用的类与接口

    我们都知道java中锁的出现是为了解决多线程情况下,线程的安全与同步问题,所谓的“线程同步机制”就是一套哦用于协调线程间的数据访问(Data Access)和活动(Activity)的机制,该机制在保证线程安全的同时,实现这些线程的共同目标。

    我们都知道在多个线程并发访问共享数据的时候会产生线程安全的问题,如何在多个线程并发的时候保证线程的安全的呢?我们很容易想到就是将并发访问的共享数据的代码,变成串行访问,这样就能做到一个共享数据一次只能被一个线程访问到,当前线程访问完成之后,其他线程才能对其访问。

   锁(Lock或synchronized)就是按照这种思路来保障线程安全的线程同步机制,用来保证线程间的“原子性”、“一致性”和“有序性”。对于被一个锁所保护的共享数据来说,任何线程如果想要对该共享数据进行访问,首先需要持有该锁。只有拥有锁的线程才能对共享数据进行访问,并且,一个锁只能被一个线程所持有,持有锁的线程在访问共享数据结束之后,必须释放锁,以便其他线程能够对共享数据进行访问。

   线程在访问共享数据之前必须先申请相应的锁,线程的这个动作被称为获取锁(acquire),在Lock接口中封装了三个锁获取方法:lock()、tryLock()、tryLock(long time, TimeUnit unit)和 lockInterruptibly()四个方法获取。线程获取锁之后,我们称这个线程持有相应的锁,上也提到了针对某些共享数据言,锁只有一个,所以锁数具有排他性的(Exclusive)。

   这里补充一个概念,就是临界区(Critical Section),所谓的临界区也就是被锁保护起来的那段代码,也就是从锁的获取到锁的释放这一段代码被称为“临界区”。所以,共享数据实际上是只能在临界区进行访问的,临界区一次也只能被一个线程执行。

   在Lock锁提供的是个锁获取方法中,lock()方法是用的最火的一个方法,这个方法的作用简单来说就是:线程获取锁,如果锁已经呗其他线程获取了,当前线程就进入等待状态。在使用Lcok锁作为同步机制的时候,相比较synchronized来说,Lock锁不会自动释放锁,这就需要我们去主动的释放锁。因此,在使用Lock锁的时候,必须在try...catch...中进行,并且将四方所的操作放在finally块中,保证锁一定被释放,防止死锁的方法。

实例:

Lock lock = new ReentrantLock();

lock.lock();
try{
    //处理任务
}catch(Exception ex){

}finally{
    lock.unlock();   //释放锁
}

  在Lock锁中,Lock只是一个接口,并不负责具体的功能实现,而lock锁功能具体的实现类是ReentrantLock,通过new ReentrantLock()的方式获取一个Lock的实例对象。

/**
 * Creates an instance of {@code ReentrantLock}.
 * This is equivalent to using {@code ReentrantLock(false)}.
 */
public ReentrantLock() {
    sync = new NonfairSync();
}

通过上述的源码可以知道的,在构建ReentrantLock实例的时候,实际上是创建了一个NonfairSync实例对象,并将该创建的对象赋值给叫sync成员变量;这个成员变量是Sync类型的,Sync是一个抽象静态内部类,在这个抽象内部类中定义了一个抽象的lock方法,如下源代码:。

/**
 * Performs {@link Lock#lock}. The main reason for subclassing
 * is to allow fast path for nonfair version.
 */
abstract void lock();

而上面的抽象方法具体是由NonfairSync来进行实现,这就是为什么在创建ReentrantLock实例的时候创建了一个NonfairSync的实例对象;

/**
 * Sync object for non-fair locks
 */
static final class NonfairSync extends Sync {
    private static final long serialVersionUID = 7316153563782823691L;

    /**
     * Performs lock.  Try immediate barge, backing up to normal
     * acquire on failure.
     */
    final void lock() {
        if (compareAndSetState(0, 1))
            se
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值