LockSupport的使用
LockSupport
1、简单概述
能够对线程进行阻塞的工具类,不止是只有对象中的wait方法才可以来进行实现。
2、几个DEMO测试
/**
* @Description 简单介绍一下LockSupport的使用 https://blog.csdn.net/shijiejiujiuba/article/details/79034307
* @Author liguang
* @Date 2022/03/10/00:15
*/
public class ThreadWattingTestOne {
public static void main(String[] args) {
final Thread thread1 = new Thread(() -> {
int i = 0;
do {
i++;
} while (i != 10000);
LockSupport.unpark(Thread.currentThread());
System.out.println("hello,world");
LockSupport.park();
System.out.println("hello,park");
LockSupport.park();
});
thread1.start();
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
LockSupport.unpark(Thread.currentThread());表示的是擦除当前线程的许可(因为默认是被something占据的),然后LockSupport.park()表示的是占用当前许可,然后有了许可之后,即可向下执行;但是发现又有LockSupport.park(),但是因为许可已经被占用了,那么这个就只能够阻塞在这里,等待拥有许可之后再来执行下面的,所以只会输出hello,world和hello,park
/**
* @Description 让线程之间进行交互
* @Author liguang
* @Date 2022/03/10/00:15
*/
public class ThreadWattingTestTwo {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
LockSupport.park();
System.out.println("hello,threadone............");
});
try {
thread1.start();
Thread.sleep(10000);
LockSupport.unpark(thread1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
因为默认的许可是被占据的,但是在主线程中10s钟被唤醒了,所以会输出hello,threadone............
/**
* @Description 线程如果因为调用park而阻塞的话,能够响应中断请求(中断状态被设置成true),但是不会抛出InterruptedException。
* @Author liguang
* @Date 2022/03/10/00:15
*/
public class ThreadWattingThree {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
LockSupport.park();
System.out.println("hello,threadone............");
});
try {
thread1.start();
Thread.sleep(10000);
thread1.interrupt();
System.out.println("hello,world");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这里因为线程许可被默认占用了,所以会一直阻塞,然后在10秒钟之后,会被中断,因为中断,所以导致线程被唤醒(但是没有抛出异常),所以会输出:
hello,threadone............
hello,world
那么接着上面的测试:
/**
* @Description 因为中断引起的,那么将导致利用工具类再次进行Park的时候无法进行park住的操作,这里是因为在检测过程中查看到是中断状态,所以不会去中断
* @Author liguang
* @Date 2022/03/10/00:15
*/
public class ThreadWattingThree {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
for (;;){
LockSupport.park();
System.out.println("hello,threadone............");
}
});
try {
thread1.start();
Thread.sleep(10000);
thread1.interrupt();
System.out.println("hello,world");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这里对于新创建的线程来说,会不断的输出
hello,threadone..........
因为LockSupport.park();在进行阻塞的时候,发现线程已经被打上了中断标记了,所以不在阻塞,因为让线程继续运行。
那么与之对应的就有另外一个方法可以来进行实现:
/**
* @Description 因为中断引起的,那么将不会阻塞住;所以这里使用工具类将线程的中断标记给清除掉,对于线程的Thread.interupted的测试来测试一下
* @Author liguang
* @Date 2022/03/10/00:15
*/
public class ThreadWattingFour {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
for (;;){
LockSupport.park("Lock");
System.out.println("hello,threadone............");
// 但是在这里加上一行数据即可
// Thread.interrupted();
}
});
try {
thread1.start();
Thread.sleep(1000);
// 因为中断引起的线程不在阻塞
thread1.interrupt();
System.out.println("hello,world");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这里是一个带参数的,而另外的地方是不带参数的。所以这样子来直接进行实现的时候,效果上是一样的。
其中:中断是可以取消线程进行阻塞的,只需要在上面的代码中加上:
Thread.interrupted();
擦除掉线程的中断状态即可。
处于waitting状态不会消耗CPU,但是CPU的切换需要消耗CPU
https://baijiahao.baidu.com/s?id=1712014506366682907&wfr=spider&for=pc