①. 通过park()和unpark(thread)⽅法来实现阻塞和唤醒线程的操作。
②. LockSupport是⼀个线程阻塞⼯具类,所有的⽅法都是静态⽅法,可以让线程在任意位置阻塞,阻塞之后也有对应的唤醒⽅法。归根结底,LockSupport调⽤的Unsafe中的native代码。
③. 官⽹解释:
LockSupport是⽤来创建锁和其他同步类的基本线程阻塞原语。
LockSupport类使⽤了⼀种名为Permit(许可)的概念来做到阻塞和唤醒线程的功能,每个线程都有⼀个许可
(permit),permit只有两个值1和零,默认是零。
可以把许可看成是⼀种(0,1)信号量(Semaphore),但与Semaphore不同的是,许可的累加上限是1。


/*
(1).阻塞
permit默认是O,所以一开始调用park()方法,当前线程就会阻塞,直到别的线程将当前线程的permit设置为1时,park方法会被唤醒,然后会将permit再次设置为O并返回。
static void park()
static void park(Object blocker)
(2).唤醒
调用unpark(thread)方法后,就会将thread线程的许可permit设置成1(注意多次调用unpark方法,不会累加,permit值还是1)会自动唤醒thread线程,即之前阻塞中的LockSupport.park()方法会立即返回。
static void unpark(Thread thread)
*/
public class LockSupportDemo {
public static void main(String[] args) {
//线程A
Thread t1=new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t"+"coming....");
LockSupport.park();
/*
如果这里有两个LockSupport.park(),因为permit的值为1,上一行已经使用了permit
所以下一行被注释的打开会导致程序处于一直等待的状态
* */
//LockSupport.park();
System.out.println(Thread.currentThread().getName()+"\t"+"被B唤醒了");
},"A");
t1.start();
//下面代码注释是为了A线程先执行
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {e.printStackTrace();}
//线程B
Thread t2=new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t"+"唤醒A线程");
//有两个LockSupport.unpark(t1),由于permit的值最大为1,所以只能给park一个通行证。
LockSupport.unpark(t1);
//LockSupport.unpark(t1);
},"B");
t2.start();
}
}