作用

用来创建锁和其他同步类的基本线程阻塞的原语.在查看AbstractQueuedSynchronizer(AQS)中,发现其底层就是使用LockSupport.park()和LockSupport.unpark()实现线程的阻塞和唤醒的.它的作用与Object上的wait和notify很像,但是还是存在一些不同.

不需要在同步代码块中调用

之前在java多线程之wait和notify中有讲过,使用wait()和notify()必须在同步代码快中才是调用,如果不是则会抛出IllegalMonitorStateException异常.但是LockSupport.park()则没有该限制.下面示例代码,如果去掉synchronized同步代码块将抛出异常.

public class App1 {

public static void main(String[] args) throws InterruptedException {

Object lock = new Object();

Thread t1 = new Thread(() -> {

synchronized (lock){

try {

lock.wait();

System.out.println(Thread.currentThread().getName()+":执行完成");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}, "t1");

t1.start();

Thread t2 = new Thread(() -> {

LockSupport.park();

System.out.println(Thread.currentThread().getName()+":执行完成");

}, "t2");

t2.start();

Thread.sleep(1000L);

//唤醒t1,t2

synchronized (lock){

lock.notify();

}

LockSupport.unpark(t2);

}

}

调用先后不会导致死锁

在使用wait和notify时,如果线程A先调用了notify,然后线程B再调用的wait没有指定超时时间,那么线程B将一直处于WAITING状态,直到有其他线程调用notify或者notifyAll.使用park和unpark则不会导致该情况发生.代码如下:

public class App2 {

public static void main(String[] args) throws InterruptedException {

Object lock = new Object();

Thread t1 = new Thread(() -> {

synchronized (lock){

System.out.println(Thread.currentThread().getName()+":开始执行");

lock.notify();

}

synchronized (lock){

try {

lock.wait();

System.out.println(Thread.currentThread().getName()+":执行完成");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}, "t1");

Thread t2 = new Thread(() -> {

System.out.println(Thread.currentThread().getName()+":开始执行");

LockSupport.unpark(Thread.currentThread());

LockSupport.park();

System.out.println(Thread.currentThread().getName()+":执行完成");

}, "t2");

t1.start();

t2.start();

t1.join();

t2.join();

}

}

响应中断的不同

使用wait使线程进入WAITING或者TIMED_WAITING,如果中断线程,线程将抛出中断异常InterruptedException.如果使用park使线程进入等待状态,并不会抛出中断异常.

public class App3 {

public static void main(String[] args) throws InterruptedException {

Object lock = new Object();

Thread t1 = new Thread(() -> {

synchronized (lock){

try {

lock.wait();

} catch (InterruptedException e) {

Thread thread = Thread.currentThread();

System.out.println(thread.getName()+":响应中断退出");

}

}

}, "t1");

Thread t2 = new Thread(() -> {

LockSupport.park();

Thread thread = Thread.currentThread();

System.out.println(thread.getName()+":响应中断退出");

}, "t2");

t1.start();

t2.start();

Thread.sleep(1000L);

System.out.println("t1.getState() = " + t1.getState());

System.out.println("t2.getState() = " + t2.getState());

t1.interrupt();

t2.interrupt();

}

}

不可重入

LockSupport很类似于二元信号量(只有1个许可证可供使用),如果这个许可还没有被占用,当前线程获取许可并继续执行;如果许可已经被占用,当前线程阻塞,等待获取许可.如果调用unpark多次释放许可,再多次调用park获取许可只能获取到一次许可.如下面代码,第二次调用park将导致线程永远的等待下去.

public class App4 {

public static void main(String[] args) {

Thread thread = Thread.currentThread();

System.out.println("第一次调用unpark");

LockSupport.unpark(thread);

System.out.println("第二次调用unpark");

LockSupport.unpark(thread);

System.out.println("第一次调用park");

LockSupport.park();

System.out.println("第二次调用park");

LockSupport.park();

System.out.println("执行完成");

}

}

上面示例代码永远也不会打印执行完成.

java unpack_java多线程之park和unpack相关推荐

  1. java中多线程之CAS(compareAndSet),Unsafe类大白话详解.

    java中多线程之CAS(compareAndSet),Unsafe类大白话详解 什么是CAS CAS原理 Unsafe类:     什么是CAS 比较并交换 在学习CAS之前,我们先了解一下JMM. ...

  2. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

  3. Java多线程之Callable、Future和FutureTask

    Java多线程之Callable接口 自己想总结一下的,看到一篇总结的更好的博客,就转载了,突然感觉真轻松,哈哈哈哈 文章转载于:Matrix海子:Java并发编程:Callable.Future和F ...

  4. Java多线程之Synchronized和Lock的区别

    Java多线程之Synchronized和Lock的区别 目录: 原始构成 使用方法 等待是否可以中断 加锁是否公平 锁绑定多个条件Condition 小结:Lock相比较Synchronized的优 ...

  5. Java多线程之CAS缺点

    Java多线程之CAS缺点 目录: 循环时间开销很大 只能保证一个共享变量的原子操作 引来ABA问题及解决方案(重点) 1. 循环时间开销很大 通过看源码,我们发现有个do while,如果CAS失败 ...

  6. Java多线程之CAS深入解析

    Java多线程之CAS深入解析 目录: CAS是什么 CAS底层原理Unsafe深入解析 CAS缺点 引子:蚂蚁花呗一面:讲一讲AtomicInteger,为什么要用CAS而不是synchronize ...

  7. Java多线程之volatile详解

    Java多线程之volatile详解 目录: 什么是volatile? JMM内存模型之可见性 volatile三大特性之一:保证可见性 volatile三大特性之二:不保证原子性 volatile三 ...

  8. Java多线程之Semaphore用法

    Java多线程之Semaphore用法 本文目录: Semaphore基本概念 Semaphore使用案例:3个停车位,6辆车去抢,走一辆,抢一个停车位. 1. Semaphore基本概念 在信号量上 ...

  9. Java多线程之CyclicBarrier用法

    Java多线程之CyclicBarrier用法 本文目录 CyclicBarrier的基本概念 CyclicBarrier的案例:集齐7颗龙珠就可以召唤神龙 1. CyclicBarrier的基本概念 ...

最新文章

  1. LeetCode简单题之设计 Goal 解析器
  2. linux系统reboot怎么退出,Linux系统肿么退出?
  3. angularjs 中的scope继承关系——(1)
  4. 康力优蓝发布新品:让AI教育从概念变成现实!
  5. java怎么xml文件解析_Java对Xml文件解析
  6. const char *p,char const *p, char * const p之间的区别
  7. VS中MFC访问MySQL的方法
  8. Bug2算法的实现(RobotBASIC环境中仿真)
  9. 将下列数组中奇数和偶数分别存放于两个不同的两个数组
  10. 输在学历的起跑线上?没关系,10本书助你技能爆表升职加薪
  11. python测试开发django-173.bootstrap实现table表格行内编辑
  12. java修改yml文件
  13. maya2020卸载不干净安装不了_Maya2020安装失败怎么办?2018却可以安装?
  14. sha加密算法介绍以及java实现sha加密算法
  15. 我去面试没带简历,你让我走人?
  16. oenwrt 进不了bios_J1900在openwrt不能正常重启的BIOS选项说明
  17. 解决服务器发回了不可路由的地址。使用服务器地址代替的问题
  18. Linux内核虚拟摄像头,Qt Opencv 在Linux下摄像头简单示例v1.0
  19. L9110电机驱动电路
  20. hexo页脚添加访客人数和总访问量

热门文章

  1. Day5/7:2021-1-29 mysql必知必会【5-12】
  2. 【關注】世界工资研究:告诉你工资的真相
  3. asp酒店房间预约系统的设计与实现
  4. Python 实现专属字典生成器
  5. TS16949认证常见问题
  6. windows xp/2003 自动登陆
  7. citidirect什么意思_citidirect.com
  8. 【IoT】NFC 卡片类型浅析
  9. PyCharm下载 (最小白)的手把手教程
  10. python 创意编程 全国-中学生Python创意编程