主要介绍LockSupport的park
和unpark
方法
public class LockSupport {
private LockSupport();
private static void setBlocker(Thread t, Object arg);
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);
static final int nextSecondarySeed();
}
park
表示当前线程阻塞,等待唤醒,相当于Object的wait方法unpark
表示唤醒线程,相当于Object的notify/notifyAll方法与Object类的wait/notify机制相比,park/unpark有两个优点: 1)以thread为操作对象更符合阻塞线程的直观定义 2)操作更精准,可以准确地唤醒某一个线程(notify随机唤醒一个线程,notifyAll唤醒所有等待的线程),增加了灵活性。 3)park/unpark不用持有锁,将锁和通知模型分离,逻辑更清晰。
另外注意:
unpark
,再执行park
操作,类似于生产/消费模型。(参考源码中注释 permit 许可含义)unpark
不能叠加,多次unpark
只需一次park
即可抵消掉。LockSupport底层使用UNSAFE
类进行操作,UNSAFE
类均是使用native方法。
public class LockSupport {
...
public static void unpark(Thread thread) {
if (thread != null)
UNSAFE.unpark(thread);
}
public static void park() {
UNSAFE.park(false, 0L);
}
...
}
public class LockSupportTest {
private static Thread thread = new Thread(new MThread());
public static void main(String[] args) throws InterruptedException {
thread.start();
LockSupport.unpark(thread);
LockSupport.unpark(thread);
LockSupport.unpark(thread);
}
public static class MThread implements Runnable{
@Override
public void run() {
try {
Thread.sleep(1000);
LockSupport.park();
System.out.println("Thread unpark 1");
LockSupport.park();
System.out.println("Thread unpark 2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
out => Thread unpark 1