LockSupport 阻塞、唤醒线程
- LockSupport类的park,unpark方法用来阻塞和唤醒线程,类似于wait、notify,下面以代码实例举例
public class LockSupportDemo {
public static void main(String[] args) {
Thread t = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println(i);
if (i == 5) {
LockSupport.park();
}
// LockSupport.park内部维护了一个count
// if (i == 8) {
// LockSupport.park();
//}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
// 先唤醒2次(n次也一样),内部将count置为1,只会阻止一次park
LockSupport.unpark(t);
// LockSupport.unpark(t);
/*try {
TimeUnit.SECONDS.sleep(8);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after 8 senconds!");
LockSupport.unpark(t);*/
}
}
①当调用park()方法时,会将_counter置为0,同时判断前值,小于1说明前面被unpark过,则直接退出,否则将使该线程阻塞。
② 当调用unpark()方法时,会将_counter置为1,同时判断前值,小于1会进行线程唤醒,否则直接退出。
形象的理解,线程阻塞需要消耗凭证(permit),这个凭证最多只有1个。当调用park方法时,如果有凭证,则会直接消耗掉这个凭证然后正常退出;但是如果没有凭证,就必须阻塞等待凭证可用;而unpark则相反,它会增加一个凭证,但凭证最多只能有1个。
③ 为什么可以先唤醒线程后阻塞线程?
因为unpark获得了一个凭证,之