美文网首页
JAVA显式锁简介

JAVA显式锁简介

作者: Cafebaby | 来源:发表于2016-03-15 23:24 被阅读260次

    在java中,协调对共享对象的访问时可以使用的机制包括synchronized,volatile以及java5.0之后新增的ReentrantLock机制。需要注意的是,ReentrantLock不是替代内置锁的方法,而是当内置锁不适用时作为可选择的高级功能。

    Lock提供了一种无条件的,可轮询的,定时的以及可中断的锁获取操作。Lock的实现中必须提供与内部所相同的内存可见性语义。ReentrantLock实现了Lock接口,其提供的互斥性和内存可见性与synchronized相同。

    使用示例(引自java并发编程实战):

    Lock lock=new ReentrantLock();
    lock.lock();
    try{
      //更新对象状态
      //捕获异常,并在必要时恢复不变性条件
    }finally{
      lock.unlock();
    }
    

    需要注意的是,unlock操作必须在finally中,否则相当于启动了"定时炸弹"。

    如何选择

    显示锁提供了额外的功能,包括定时,可中断,公平性以及非块结构加锁,此外性能上高于内置锁。
    内置锁相对易于调试,通过线程转储可以给出哪些调用栈获得了哪些锁,并能检测和识别发生死锁的线程。它也是JVM的内置属性,在未来优化性能的空间更大。

    接口代码

    public interface Lock {
    
        /*请求锁,实现时应该考虑能够检测出错误的使用,如避免死锁或者抛出未经检查的异常     */
        void lock();
    
        /*支持在请求锁的时候被中断     */
        void lockInterruptibly() throws InterruptedException;
    
        /*如果请求锁时锁可用则立即获取并返回true,否则立即返回false     */
        boolean tryLock();
    
        /*如果请求锁时锁可用则立即获取并返回true ,否则线程进入不可调度状态直到以下三种情况:
        *线程获取锁
        *其他线程中断当前线程
        *超时
        */
        boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    
        void unlock();
    
        /*返回一个新的绑定到当前lock实例的Condition对象实例     */
        Condition newCondition();
    }
    
    public interface Condition{
    
        /**
        *使当前线程等待直到被唤醒或者被中断。
        *与该Condition关联的锁会被自动释放,然后线程进入休直到以下四种情况:
        *1.其他线程调用Condition的signal方法且当前线程被选为被唤醒线程;
        *2.其他线程调用signalAll方法;
        *3.其他线程中断了当前线程;
        *4.假唤醒。
        *
        *当前线程在方法返回之前必须重新请求锁
        */
        void await() throws InterruptedException;
    
        /*相对上一个方法,该方法不响应中断,直到被唤醒*/
        void awaitUninterruptibly();
    
      /*等待直到被唤醒,中断或者指定时间超时*/
        long awaitNanos(long nanosTimeout) throws InterruptedException;
    
        /*等同于awaitNanos(unit.toNanos(time)) > 0*/
        boolean await(long time,TimeUnit unit) throws InterruptedException;
    
        /*指定deadline*/
        boolean awaitUntil(Date deadline) throws InterruptedException;
        void signal();
        void signalAll();
    }
    

    Condition

    在接口中出现了Condition类,在此简单的介绍一下条件队列:条件队列能使一组线程通过某种方式等待特定的条件为真,该队列中的元素是一个个正在等待相关条件的线程。

    在java中,每个对象都可以作为一个条件队列,可以在Object对象中看到,每个对象都拥有wait(),notify()以及notifyAll()方法。而内部锁机制与内部条件队列是相互关联的,要调用某对象条件队列的方法时,必须持有该对象上的锁。只有能对状态进行检查时,才能在某个条件上等待,并且只有能修改状态时,才能从条件等待中释放一个线程。

    相关文章

      网友评论

          本文标题:JAVA显式锁简介

          本文链接:https://www.haomeiwen.com/subject/vahqlttx.html