Lock和LockSupport

一、Lock接口

java.util.concurrent.locks.Lock只是一个接口,看下有哪些方法

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}

上面几个方法接口定义已经很明确了,ReentrantLock和ReadWriteLock是此接口的实现。

二、LockSupport类

LockSupport包含了以下方法,基本围绕着park和unpark,park的作用是给线程上锁,也就是阻塞,unpark方法是释放锁。

public class LockSupport {
    public static void unpark(Thread thread)
    public static void park(Object blocker)
    public static void parkNanos(Object blocker, long nanos)
    public static void parkUntil(Object blocker, long deadline)
    public static Object getBlocker(Thread t) 
    public static void park()
    public static void parkNanos(long nanos)
    public static void parkUntil(long deadline)
}

看下park方法的实现

/**
     * Disables the current thread for thread scheduling purposes unless the
     * permit is available.
     *
     * 

If the permit is available then it is consumed and the call returns * immediately; otherwise * the current thread becomes disabled for thread scheduling * purposes and lies dormant until one of three things happens: * *

    *
  • Some other thread invokes {@link #unpark unpark} with the * current thread as the target; or * *
  • Some other thread {@linkplain Thread#interrupt interrupts} * the current thread; or * *
  • The call spuriously (that is, for no reason) returns. *
* *

This method does not report which of these caused the * method to return. Callers should re-check the conditions which caused * the thread to park in the first place. Callers may also determine, * for example, the interrupt status of the thread upon return. * * @param blocker the synchronization object responsible for this * thread parking * @since 1.6 */ public static void park(Object blocker) { Thread t = Thread.currentThread(); setBlocker(t, blocker); UNSAFE.park(false, 0L); setBlocker(t, null); }

blocker是用来表示当前线程,当发生死锁时,通过blocker对象上下文,可以追踪是具体的哪一个线程以及对应的代码。

  1. 值得注意的是当执行上述park方法时,执行到UNSAFE.park(false, 0L);这一行时,会卡住,因为当前线程被阻塞了。所以下一行代码 setBlocker(t, null);不会立即执行。只有调用unpark方法之后,setBlocker(t, null);这行代码才会执行。
  2. 另外unpark方法允许出现在park方法调用前。也就是先调用unpark后,再调用park方法,会直接通过,不会发生线程阻塞。想理解这个,首先要理解LockSupport中许可permit的概念。也就是park方法注释“Disables the current thread for thread scheduling purposes unless the permit is available.”。许可允许提前获得,一旦获得许可后,执行park方法就不会发生阻塞。

你可能感兴趣的:(Lock和LockSupport)