本篇讲解LockSupport.park会让线程进入什么状态,以及如何解除.
无代码不发言
public static void main(String[] args) throws Exception {
Thread parkThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "进入park");
LockSupport.park(this);
System.out.println(Thread.currentThread().getName() + "解除park");
}
}, "parkThread");
parkThread.start();
}
当线程执行到LockSupport.park(this)这句之后,线程会进入到什么状态呢?
编译执行之后,通过jstack查看
可以看到,线程进入到WAITING,这里的状态是线程在JVM中的线程状态,那么这个线程在操作系统中的状态又是什么呢?
根据上面的堆栈信息,可以看到操作系统的线程ID=0xde9
先将这个十六进制的0xde9转成十进制3561
通过ps命令查看本进程中的操作系统线程状态
从图中看到,线程的状态是Sleep
说完了线程的状态,那么再来说下,如何解除线程的WAITING/Sleep,让线程继续运行呢?
主要有两种方式
第一种方式通过LockSupport.unpark(thread)
Thread unParkThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "进入unPark");
LockSupport.unpark(parkThread);
System.out.println(Thread.currentThread().getName() + "退出unPark");
}
}, "unParkThread");
unParkThread.start();
第二种方式通过thread.interrupt()
Thread unParkThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "进入中断");
parkThread.interrupt();
System.out.println(Thread.currentThread().getName() + "退出中断");
}
}, "unParkThread");
unParkThread.start();
学习过AQS的同学应该都看过下面这张图
没有获取到锁的线程,进入到同步队列中,通过park进入等待状态.
红色的箭头会让线程从等待状态唤醒,继续尝试获取锁.红色箭头的体现就是调用unpark()或者interrupt(),也就是上面我们所说的两种方式.
公众号