Lock接口简介

1.引子

锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源,解决数据的一致性问题。在Lock接口出现之前,Java程序是靠synchronized关键字实现锁功能的,而Java SE 5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功能,只是在使用时需要显式地获取和释放锁。虽然它缺少了隐式获取释放锁的便捷性,但是却拥有了锁获取与释放的可操作性、可中断的获取锁以及超时获取锁等多种synchronized关键字所不具备的同步特性。

使用synchronized关键字将会隐式地获取锁,当synchronized的方法或代码块执行完成再释放。这种方式简化了同步的管理,可是扩展性没有显示的锁获取和释放来的好。在比较复杂的同步控制中,可操作性不如显式锁来的灵活. 例如,针对一个场景,手把手进行锁获取和释放,先获得锁A,然后再获取锁B,当锁B获得后,释放锁A同时获取锁C,当锁C获得后,再释放B同时获取锁D,以此类推。这种场景下,synchronized关键字就不那么容易实现了,而使用Lock却容易许多。

2.Lock的主要内容

2.1 显式锁Lock的简单使用

和synchronized的同步代码块类似,在“lock.lock()”至“finally“之间的try代码段是锁控制的并发代码片段;lock.lock()进行锁获取,和synchronized代码块生成的字节码关键字“moniterenter”作用类似,而"lock.unlock()"释放锁和synchronized代码块生成“moniterexit”作用类似,其包裹在“finally”保证锁一定会被释放,防止锁一直被线程所持有。

        Lock lock = new ReentrantLock();
        lock.lock();
        try{
            //省略锁控制的代码
        }finally {
            lock.unlock();
        }

2.2 Lock接口的抽象方法

    public interface Lock {
        //获取锁
        void lock();

        //响应中断地获取锁
        void lockInterruptibly() throws InterruptedException;

        //尝试获取锁,若获取锁失败,方法立即返回
        boolean tryLock();

        //在给定的时间内尝试获取锁,在此时间段内仍未获取到锁,最终方法还是将返回
        boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

        //释放锁
        void unlock();

        /**
         * 返回一个与当前锁绑定的新Condition实例,可以绑定多个Condition实例<br/>
         * 此Condition实例用作线程通信,类似于Object的nofify()/wait()
         */
        Condition newCondition();
    }

 2.3 方法详细描述

void lock():获取锁,当锁获得后,从此方法立即返回
void lockInterruptibly():可中断地获取锁,此方法响应中断,在锁获取过程中
若某个时刻当前线程是中断状态,则立即抛出中断异常
tryLock():尝试非阻塞地获取锁,调用此方法若马上能获取到锁,则返回true,若不能立即获取到锁,则立即从方法返回false
tryLock(long time,TimeUnit unit):在给定时间内获取锁,在这3种情况下方法返回①在给定时间内获得了锁,返回true②当前线程被中断,抛出异常,方法返回③超过给定时间,方法返回false。
void unLock():释放锁
Condition newCondition:返回一个与当前锁绑定的新Condition实例

 2.4 Lock接口提供的synchronized关键字所不具备的主要特性

特性 描述
尝试非阻塞地获取锁 当前线程尝试获取锁,如果此时锁没被其他线程获取到,则当前线程获取锁成功
响应中断地获取锁 当获取到锁的线程被中断时,中断异常将抛出,同时释放锁
超时地获取锁 在给定的时间内获取锁,如果超出给定时间仍未获取到锁,方法仍要返回

 参考:《Java并发编程的艺术》方腾飞

原文地址:https://www.cnblogs.com/gocode/p/usage-of-lock-interface.html