java线程并发包util.concurrent的研究(四)

Lock接口

看看Lock接口的结构和lock接口的具体实现类ReentrantLock,通过对它们的揣摩,能多少知道一些“锁”的工作原理。

Lock接口:

package edu.emory.mathcs.backport.java.util.concurrent.locks;

import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;

public interface Lock {

    /**

     * Acquires the lock.

     * <p>If the lock is not available then

     * the current thread becomes disabled for thread scheduling

     * purposes and lies dormant until the lock has been acquired.

     * <p><b>Implementation Considerations</b>

     * <p>A <tt>Lock</tt> implementation may be able to detect

     * erroneous use of the lock, such as an invocation that would cause

     * deadlock, and may throw an (unchecked) exception in such circumstances.

     * The circumstances and the exception type must be documented by that

     * <tt>Lock</tt> implementation.

     *

     **/

void lock();

方法功能:

申请锁

详细描述:

如果当前锁无效(无法获得),则申请该锁的线程将挂起等待直到获得有效的锁。

对实现类的考虑:

具体实现类要能够检测一些使用中的错误(例如死锁)并按照相应情况抛出异常。这些具体的异常情况必须在Lock的实现类中有所体现。

 

    /**

     * Acquires the lock unless the current thread is

     * {@link Thread#interrupt interrupted}.

     * <p>Acquires the lock if it is available and returns immediately.

     * <p>If the lock is not available then

     * the current thread becomes disabled for thread scheduling

     * purposes and lies dormant until one of two things happens:

     * <ul>

     * <li>The lock is acquired by the current thread; or

     * <li>Some other thread {@link Thread#interrupt interrupts} the current

     * thread, and interruption of lock acquisition is supported.

     * </ul>

     * <p>If the current thread:

     * <ul>

     * <li>has its interrupted status set on entry to this method; or

     * <li>is {@link Thread#interrupt interrupted} while acquiring

     * the lock, and interruption of lock acquisition is supported,

     * </ul>

     * then {@link InterruptedException} is thrown and the current thread's

     * interrupted status is cleared.

     *

     * <p><b>Implementation Considerations</b>

     *

     * <p>The ability to interrupt a lock acquisition in some

     * implementations may not be possible, and if possible may be an

     * expensive operation.  The programmer should be aware that this

     * may be the case. An implementation should document when this is

     * the case.

     *

     * <p>An implementation can favor responding to an interrupt over

     * normal method return.

     *

     * <p>A <tt>Lock</tt> implementation may be able to detect

     * erroneous use of the lock, such as an invocation that would

     * cause deadlock, and may throw an (unchecked) exception in such

     * circumstances.  The circumstances and the exception type must

     * be documented by that <tt>Lock</tt> implementation.

     *

     * @throws InterruptedException if the current thread is interrupted

     * while acquiring the lock (and interruption of lock acquisition is

     * supported).

     *

     * @see Thread#interrupt

     *

     **/

    void lockInterruptibly() throws InterruptedException;

       方法功能:

              申请锁,除非当前申请线程被中断。

       详细描述:

申请锁时如果锁是有效的(未被其它线程所占用),则立即返回;如果锁是无效的,则申请该锁的线程(即称为当前线程)将挂起等待直到获得有效的锁,这时会有两种情况发生:

1.  当前线程获得锁。

2.  当前线程被其它线程所中断,而且锁申请的中断被支持。如果当前线程对这个方法来说存在线程被中断的状态的登记;或者锁申请的中断被支持,则一个InterruptedException异常将被抛出,当前线程的中断状态将被清除。

对实现类的考虑:

       对于某些实现来说支持锁获取的中断可能是不可能的,如果可能也要花费大量的操作。开发人员要注意到这个事实。写实现类的文档时要对它有所说明。一个实现能支持根据在正常方法上的中断而返回。具体实现类要能够检测一些使用中的错误(例如死锁)并按照相应情况抛出异常。这些具体的异常情况必须在Lock的实现类中有所体现。当正在申请锁时(如果申请锁的中断被支持),当前线程被中断,则一个中断异常将被抛出。

 

    /**

     * Acquires the lock only if it is free at the time of invocation.

     * <p>Acquires the lock if it is available and returns immediately

     * with the value <tt>true</tt>.

     * If the lock is not available then this method will return

     * immediately with the value <tt>false</tt>.

     * <p>A typical usage idiom for this method would be:

     * <pre>

     *      Lock lock = ...;

     *      if (lock.tryLock()) {

     *          try {

     *              // manipulate protected state

     *          } finally {

     *              lock.unlock();

     *          }

     *      } else {

     *          // perform alternative actions

     *      }

     * </pre>

     * This usage ensures that the lock is unlocked if it was acquired, and

     * doesn't try to unlock if the lock was not acquired.

     *

     * @return <tt>true</tt> if the lock was acquired and <tt>false</tt>

     * otherwise.

     **/

      

    boolean tryLock();

方法功能:

只当锁是有效的(没有线程占用)时,才获取锁。

       详细描述:

              如果锁是有效的,则获取锁并立即返回true;否则将立即返回false

              该方法的典型用例:

                  Lock lock = ...;

                 if (lock.tryLock()) {

               try {

                   // manipulate protected state

               } finally {

                   lock.unlock();

               }

           } else {

               // perform alternative actions

           }

这种用法确保如果锁被获得的话,将被解锁,而如果锁没有被获得的话,不用去尝试解锁。

 

    /**

     * Acquires the lock if it is free within the given waiting time and the

     * current thread has not been {@link Thread#interrupt interrupted}.

     *

     * <p>If the lock is available this method returns immediately

     * with the value <tt>true</tt>.

     * If the lock is not available then

     * the current thread becomes disabled for thread scheduling

     * purposes and lies dormant until one of three things happens:

     * <ul>

     * <li>The lock is acquired by the current thread; or

     * <li>Some other thread {@link Thread#interrupt interrupts} the current

     * thread, and interruption of lock acquisition is supported; or

     * <li>The specified waiting time elapses

     * </ul>

     * <p>If the lock is acquired then the value <tt>true</tt> is returned.

     * <p>If the current thread:

     * <ul>

     * <li>has its interrupted status set on entry to this method; or

     * <li>is {@link Thread#interrupt interrupted} while acquiring

     * the lock, and interruption of lock acquisition is supported,

     * </ul>

     * then {@link InterruptedException} is thrown and the current thread's

     * interrupted status is cleared.

     * <p>If the specified waiting time elapses then the value <tt>false</tt>

     * is returned.

     * If the time is

     * less than or equal to zero, the method will not wait at all.

     *

     * <p><b>Implementation Considerations</b>

     * <p>The ability to interrupt a lock acquisition in some implementations

     * may not be possible, and if possible may

     * be an expensive operation.

     * The programmer should be aware that this may be the case. An

     * implementation should document when this is the case.

     * <p>An implementation can favor responding to an interrupt over normal

     * method return, or reporting a timeout.

     * <p>A <tt>Lock</tt> implementation may be able to detect

     * erroneous use of the lock, such as an invocation that would cause

     * deadlock, and may throw an (unchecked) exception in such circumstances.

     * The circumstances and the exception type must be documented by that

     * <tt>Lock</tt> implementation.

     *

     * @param time the maximum time to wait for the lock

     * @param unit the time unit of the <tt>time</tt> argument.

     * @return <tt>true</tt> if the lock was acquired and <tt>false</tt>

     * if the waiting time elapsed before the lock was acquired.

     *

     * @throws InterruptedException if the current thread is interrupted

     * while acquiring the lock (and interruption of lock acquisition is

     * supported).

     *

     * @see Thread#interrupt

     *

     **/

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

       方法功能:

              在给定时间内获取锁

       详细描述:

如果在一定的等待时间内锁是有效的,并且当前线程没有被中断的话,当前线程将获得该锁;如果锁是无效的,则当前线程将挂起直到以下的三种情况之一发生:

1.在一定的时间内锁被当前线程获得;

2.其它线程中断了当前线程,并且锁申请的中断被支持;

3.在一定时间内当前线程没有获得锁,即等待时间超出了给定值。

情况1发生时,锁被当前线程获取,并返回true

情况2发生时,如果对本方法来讲,当前线程的中断状态被登记或者申请锁时,锁申请的中断被支持,则InterruptedException将被抛出,当前线程的中断状态被清除。

情况3发生时,返回false。如果给定的时间期限<=0,则本方法将不作等待。

       对实现类的考虑:

一些实现支持锁获取的中断不大可能,而且如果支持的话将付出大量的操作。开发人员应该注意这种情况。并且实现类必须将此情况写入文档。一个实现类能够在执行方法时被中断并返回,或者报告超时。具体实现类要能够检测一些使用中的错误(例如死锁)并按照相应情况抛出异常。这些具体的异常情况必须在Lock的实现类中有所体现。当正在申请锁时(如果申请锁的中断被支持),当前线程被中断,则一个中断异常将被抛出。

       方法说明:

              参数1:等待时间(超时时间)

              参数2TimeUnit类对象

              返回值:当获得锁时返回true,当等待超时时返回false

       异常情况:如果当前线程在获取锁时被中断(锁申请的中断被支持),则InterruptedException被抛出

    /**

     * Releases the lock.

     * <p><b>Implementation Considerations</b>

     * <p>A <tt>Lock</tt> implementation will usually impose

     * restrictions on which thread can release a lock (typically only the

     * holder of the lock can release it) and may throw

     * an (unchecked) exception if the restriction is violated.

     * Any restrictions and the exception

     * type must be documented by that <tt>Lock</tt> implementation.

     **/

void unlock();

方法功能:

       释放锁。

对实现类的建议:

锁实现类可以对能够释放锁的线程附加限制,典型的是锁的持有者能够释放锁,当限制被违背时,一个异常将被抛出。任何限制和异常都必须被写入到实现类的文档中。

 

    /**

     * Returns a new {@link Condition} instance that is bound to this

     * <tt>Lock</tt> instance.

     * <p>Before waiting on the condition the lock must be held by the

     * current thread.

     * A call to {@link Condition#await()} will atomically release the lock

     * before waiting and re-acquire the lock before the wait returns.

     * <p><b>Implementation Considerations</b>

     * <p>The exact operation of the {@link Condition} instance depends on the

     * <tt>Lock</tt> implementation and must be documented by that

     * implementation.

     *

     * @return A new {@link Condition} instance for this <tt>Lock</tt>

     * instance.

     * @throws UnsupportedOperationException if this <tt>Lock</tt>

     * implementation does not support conditions.

     **/

Condition newCondition();

方法功能:

       返回一个新的被绑定到锁上的条件实例。

详细描述:

在调用本方法等待条件实例返回前,当前线程必须首先获得锁。在等待前要调用Condition.await方法自动释放锁和并且在等待返回前重新申请锁。

       对实例类的建议:

              条件实例操作依靠于锁实现,并且必须写入实例类的文档中。

       方法说明:

              返回值:返回一个新的被绑定到锁上的条件实例。

              异常情况:如果锁不支持条件,则抛出UnsupportedOperationException异常。

 

}

总结一下,lock接口的方法列表

方法名

功能

备注

lock

获取锁

如果获取不到锁的话,当前线程将挂起直到获得锁。我把它称作“死等”式获取。

lockInterruptibly

以可被中断的方式获取锁

如果获取不到锁的话,当前线程将挂起直到获得锁或者当前线程被其他线程中断。我把它称作“悲观死等”式获取。

tryLock

尝试获取锁

如果锁有效的话,当前线程立即获取锁并返回true,否则返回false。我称之为“试探”式获取

tryLock(long time, TimeUnit unit)

具有超时机制的尝试获取锁

如果锁有效的话,当前线程立即获取锁并返回true;否则等待一个给定的时间,如果在这时间内获得锁,则返回true,否则返回false;另外像lockInterruptibly一样线程有可能在获取的过程中被中断。我称之为“试探超时”式获取

releaseLock

释放锁

 

newCondition

返回当前锁的条件

 

比较四种lock方法来讲,“试探”式和“试探超时”式获取锁的方式效率较高。而“死等”和“悲观死等”式效率低,而且在并发线程较多时增加了系统的资源开销,并且当持有锁的线程没有释放锁便被kill掉时,那些等待锁的线程将被永远的挂起。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值