Module  java.base

Interface Lock

  • 所有已知实现类:
    ReentrantLockReentrantReadWriteLock.ReadLockReentrantReadWriteLock.WriteLock


    public interface Lock
    Lock实现提供比使用synchronized方法和语句可以获得的更广泛的锁定操作。 它们允许更灵活的结构化,可能具有完全不同的属性,并且可以支持多个关联的Condition对象。

    锁是用于通过多个线程控制对共享资源的访问的工具。 通常,锁提供对共享资源的独占访问:一次只能有一个线程可以获取锁,并且对共享资源的所有访问都要求首先获取锁。 但是,某些锁可能允许并发访问共享资源,例如ReadWriteLock的读取锁。

    使用synchronized方法或语句提供对与每个对象相关联的隐式监视锁的访问,但是强制所有锁获取和释放以块结构的方式发生:当获取多个锁时,它们必须以相反的顺序被释放,并且所有的锁都必须被释放在与它们相同的词汇范围内。

    虽然synchronized方法和语句的范围化机制使得使用监视器锁更容易编程,并且有助于避免涉及锁的许多常见编程错误,但有时您需要以更灵活的方式处理锁。 例如,用于遍历并发访问的数据结构的一些算法需要使用“手动”或“链锁定”:您获取节点A的锁定,然后获取节点B,然后释放A并获取C,然后释放B并获得D等。 Lock接口的实现使得能够通过允许在不同范围内获取和释放锁来实现这种技术,并允许以任何顺序获取和释放多个锁。

    随着这种增加的灵活性会增加责任。 不存在块结构锁定的去除锁的自动释放,与发生synchronized方法和语句。 在大多数情况下,应使用以下惯用语:

       Lock l = ...; l.lock(); try { // access the resource protected by this lock } finally { l.unlock(); } 
    当在不同范围内发生锁定和解锁时,必须注意确保在锁定时执行的所有代码由try-finally或try-catch保护,以确保在必要时释放锁定。

    Lock实现提供了使用synchronized方法和语句的附加功能,通过提供非阻塞尝试来获取锁( tryLock() ),尝试获取可被中断的锁( lockInterruptibly() ,以及尝试获取可以超时( tryLock(long, TimeUnit) )。

    一个Lock类还可以提供与隐式监视锁定的行为和语义完全不同的行为和语义,例如保证排序,非重入使用或死锁检测。 如果一个实现提供了这样的专门的语义,那么实现必须记录这些语义。

    请注意, Lock实例只是普通对象,它们本身可以用作synchronized语句中的目标。 获取Lock实例的监视器锁与调用该实例的任何lock()方法没有特定关系。 建议为避免混淆,您永远不会以这种方式使用Lock实例,除了在自己的实现中。

    除非另有说明,传递任何参数的null值将导致抛出NullPointerException

    内存同步

    所有Lock实现必须执行与内置监视器锁相同的内存同步语义,如Chapter 17 of The Java™ Language Specification所述

    • 成功的lock操作具有与成功锁定动作相同的内存同步效果。
    • 成功的unlock操作具有与成功解锁动作相同的内存同步效果。
    不成功的锁定和解锁操作以及重入锁定/解锁操作,不需要任何内存同步效果。

    实施注意事项

    锁定采集(可中断,不可中断和定时)的三种形式在性能特征,排序保证或其他实现质量方面可能不同。 此外,在给定的Lock课程中,中断正在获取锁的能力可能不可用。 因此,不需要实现对所有三种形式的锁获取完全相同的保证或语义,也不需要支持正在进行的锁获取的中断。 需要一个实现来清楚地记录每个锁定方法提供的语义和保证。 它还必须遵守此接口中定义的中断语义,只要支持锁获取的中断,即全部或仅在方法输入。

    由于中断通常意味着取消,并且检查中断通常是不频繁的,所以实现可以有利于通过正常方法返回来响应中断。 即使可以显示中断发生在另一个动作可能已经解除了线程之后,这是真的。 一个实现应该记录这个行为。

    从以下版本开始:
    1.5
    另请参见:
    ReentrantLockConditionReadWriteLock
    • 方法详细信息

      • lock

        void lock​()
        获得锁。

        如果锁不可用,则当前线程将被禁用以进行线程调度,并处于休眠状态,直到获取锁。

        实施注意事项

        A Lock实现可能能够检测锁的错误使用,例如将导致死锁的调用,并且可能在这种情况下抛出(未检查)异常。 情况和异常类型必须由该Lock实现记录。

      • lockInterruptibly

        void lockInterruptibly​()
                        throws InterruptedException
        获取锁定,除非当前线程是interrupted

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

        如果锁不可用,那么当前线程将被禁用以进行线程调度,并且处于休眠状态,直到发生两件事情之一:

        • 锁是由当前线程获取的; 要么
        • 一些其他线程当前线程interrupts ,并支持锁中断中断。

        如果当前线程:

        • 在进入该方法时设置了中断状态; 要么
        • interrupted同时获取锁,并支持锁中断,
        则抛出InterruptedException ,并清除当前线程的中断状态。

        实施注意事项

        在某些实现中中断锁获取的能力可能是不可能的,如果可能的话可能是昂贵的操作。 程序员应该知道,可能是这种情况。 在这种情况下,实施应该记录。

        一个实现可以有利于通过正常的方法返回来响应中断。

        一个Lock实现可能能够检测到锁的错误使用,例如将导致死锁的调用,并且可能在这种情况下抛出(未检查)异常。 情况和异常类型必须由该Lock实现记录。

        异常
        InterruptedException - 如果当前线程在获取锁定时中断(并且支持锁定获取的中断)
      • tryLock

        boolean tryLock​()
        只有在调用时才可以获得锁。

        获取锁定,如果可用,并立即返回值为true 如果锁不可用,则此方法将立即返回值为false

        此方法的典型用法是:

           Lock lock = ...; if (lock.tryLock()) { try { // manipulate protected state } finally { lock.unlock(); } } else { // perform alternative actions } 
        此用法可确保锁定已被取消,如果未获取锁定,则不会尝试解锁。
        结果
        true如果锁被收购, false另外 false
      • tryLock

        boolean tryLock​(long time,
                        TimeUnit unit)
                 throws InterruptedException
        如果在给定的等待时间内是空闲的,并且当前的线程尚未被interrupted获取该锁。

        如果锁可用,此方法将立即返回值为true 如果锁不可用,则当前线程将被禁用以进行线程调度,并处于休眠状态,直至发生三件事情之一:

        • 锁是由当前线程获取的; 要么
        • 一些其他线程当前线程interrupts ,并且支持中断锁获取; 要么
        • 指定的等待时间过去了

        如果锁获取,则返回值true

        如果当前线程:

        • 在进入该方法时设置了中断状态; 要么
        • interrupted,同时获取锁,并支持锁中断,
        然后抛出InterruptedException ,并清除当前线程的中断状态。

        如果指定的等待时间过去,则返回值false 如果时间小于或等于零,该方法根本不会等待。

        实施注意事项

        在某些实现中中断锁获取的能力可能是不可能的,如果可能的话可能是昂贵的操作。 程序员应该知道,可能是这种情况。 在这种情况下,实施应该记录。

        实现可以有助于通过正常的方法返回来响应中断或报告超时。

        A Lock实现可能能够检测锁的错误使用,例如将导致死锁的调用,并且可能在这种情况下抛出(未检查)异常。 情况和异常类型必须由该Lock实现记录。

        参数
        time - 等待锁的最长时间
        unit - time参数的时间单位
        结果
        true如果锁已被获取,并且 false如果在获取锁之前经过的等待时间
        异常
        InterruptedException - 如果当前线程在获取锁定时中断(并且支持锁定获取的中断)
      • unlock

        void unlock​()
        释放锁。

        实施注意事项

        一个Lock实现通常会限制哪个线程可以释放一个锁(通常只有锁的持有者可以释放它),并且如果限制被违反则可能引发(未检查)异常。 任何限制和异常类型必须由该Lock实现记录。

      • newCondition

        Condition newCondition​()
        返回一个新Condition绑定到该实例Lock实例。

        在等待条件之前,锁必须由当前线程保持。 调用Condition.await()将在等待之前将原子释放锁,并在等待返回之前重新获取锁。

        实施注意事项

        Condition实例的确切操作取决于Lock实现,必须由该实现记录。

        结果
        一个新的27062366376707实例为这个Lock实例
        异常
        UnsupportedOperationException - 如果这个 Lock实现不支持条件