LockSupport的park()和 unpark()方法

LockSupport是创建锁和其他同步类的基本线程堵塞原语。
LockSupport通过许可机制来控制是否堵塞线程,unpark()发放许可,线程不堵塞,park()消费许可,线程堵塞。除此之外,LockSupport还支持传递一个参数的形式,这个参数可以在堵塞的时候获得,具体解释请看下面。


park()和unpark()提供了类似wait()和notify()的机制,但是并不用获得对象的监视器,而是获得许可,park()就是堵塞,挂起,不许可的意思。unpark()就是发放许可。unpark()可以在park()之前执行,先发放许可,park()再消费许可,假如有许可子直接返回,并不堵塞,假如没有许可的话则会堵塞线程,这个许可是直接和线程关联的,并且一个线程只能有一个许可。

park()方法:

挂起当前线程,除非线程获得了许可证。
假如线程没有许可证,那么会将线程挂起,
假如线程有许可,被调用的话会直接返回。

线程不再挂起的条件:

  1. 当有其他的线程调用了unpark()将当前线程作为参数的时候。
  2. 有线程中断当前线程。
  3. 调用没有逻辑的返回。

注意:
此方法并不知道是何种原因造成的返回,调用者应该在第一时间检查是什么原因造成的线程暂停,调用者也会可能结束,例如中断返回的时候。

    public static void park(Object blocker) {
        Thread t = Thread.currentThread();
        setBlocker(t, blocker);
        UNSAFE.park(false, 0L);
        setBlocker(t, null);
    }

unpark()方法:
给给定的线程发放许可,假如线程因为park()而堵塞,那么线程将会不再堵塞,假如线程没有启动,那么这个操作将不会有任何效果,不会发放许可。

 public static void unpark(Thread thread) {
        if (thread != null)
            UNSAFE.unpark(thread);
    }

另外的,你还可以在park()里面传递一个对象,可以通过调用getBlocker()来获得,不过只有在线程已经堵塞的时候才会获得这个对象,当线程不再堵塞的时候将无法在或的这个对象。你想一下就会明白,因为许可只有一次,当你第一次堵塞的时候传递了一个对象,当获得许可之前你都可以获得这个对象,但是如果一旦这个线程获得了许可,就不可以在获得这个对象了。假如有一辆载满香猪的货车过红绿灯,当红灯堵塞的时候,所有的人都可以看到货车里面载的是香猪,但是当绿灯了,货车获得许可,所有的人都无法知道货车下次再经过的时候会带什么货,有些牵强,但希望帮助理解一下。

\color{red}{注意:在jdk注释中有这么一句话:这些方法被设计用来作为创建高级同步实用工具的工具,它们本身对大多数并发控制应用程序没有用处。所以我们接下来就用它来实现锁}

你可能感兴趣的:(LockSupport的park()和 unpark()方法)