个人随笔
目录
线程阻塞与唤醒之LockSupport的park()方法和unpark(Thead t)
2022-12-25 21:21:43

LockSupport类的park()方法和unpark(Thead t)方法通常用于线程之间的阻塞和唤醒,但是这两个方法比较强大,前后不需要加锁,执行顺序也不限制,他们之间的约束靠的是信号量,下面是例子。

1、正常使用的代码

  1. public class ParkAndUnPark {
  2. public static void main(String[] args) {
  3. Thread t1 = new Thread(()->{
  4. System.out.println(Thread.currentThread().getName()+"进来啦,然后被park阻塞");
  5. //消耗一个凭证,若没得消耗则阻塞
  6. LockSupport.park();
  7. System.out.println(Thread.currentThread().getName()+"被唤醒啦");
  8. },"t1");
  9. t1.start();
  10. try {
  11. Thread.sleep(2000);
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. new Thread(()->{
  16. System.out.println(Thread.currentThread().getName()+"unpark唤醒了t1");
  17. //产生一个凭证,最多产生一个,不管unpark多少次
  18. LockSupport.unpark(t1);
  19. },"t2").start();
  20. }
  21. }

输出结果

  1. t1进来啦,然后被park阻塞
  2. t2unpark唤醒了t1
  3. t1被唤醒啦

跟预想的一致。

2、park()和unpark()不需要加锁

它们之间靠的是凭证,park()消耗一个凭证,若没有则阻塞,有则不阻塞。unpark()生成一个凭证,不管调用多少次都只能生成一个,最大是1.

3、如果先执行unpark()后执行park()则不会阻塞

原因是unpark()先放了一个凭证,所以park()的时候,凭证已经存在则不阻塞继续执行。

  1. public class ParkAndUnPark {
  2. public static void main(String[] args) {
  3. Thread t1 = new Thread(()->{
  4. try {
  5. Thread.sleep(3000);
  6. } catch (InterruptedException e) {
  7. // TODO Auto-generated catch block
  8. e.printStackTrace();
  9. }
  10. System.out.println(Thread.currentThread().getName()+"进来啦,然后被park阻塞");
  11. //消耗一个信号量,若没得消耗则阻塞
  12. LockSupport.park();
  13. System.out.println(Thread.currentThread().getName()+"被唤醒啦");
  14. },"t1");
  15. t1.start();
  16. try {
  17. Thread.sleep(2000);
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21. new Thread(()->{
  22. System.out.println(Thread.currentThread().getName()+"unpark唤醒了t1");
  23. //产生一个信号量,最多产生一个,不管unpark多少次
  24. LockSupport.unpark(t1);
  25. },"t2").start();
  26. }
  27. }
  1. t2unpark唤醒了t1
  2. t1进来啦,然后被park阻塞
  3. t1被唤醒啦
 237

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2