LockSupport

LockSupport 是一个线程阻塞工具类,所有的方法都是静态方法,可以让线程在任意位置阻塞,阻塞之后也有对应的唤醒方法。归根结底,LockSupport调用的Unsafe中的native代码

  • 通过park()和unpark(thread)方法来实现阻塞和唤醒线程的操作
  • LockSupport类使用了一种名为 Permit(许可) 的概念来做到阻塞和唤醒线程的功能,每个线程都有一个许可(permit),permit只有两个值 1和零,默认是零

    注意上面的123方法,都有一个blocker,这个blocker是用来记录线程被阻塞时被谁阻塞的。用于线程监控和分析工具来定位原因的。

① 阻塞方法

permit默认是0,所以一开始调用park()方法,当前线程就会阻塞,直到别的线程将当前线程的permit设置为1时, park方法会被唤醒,然后会将permit再次设置为0并返回permit 表示当前线程是否处于运行状态

  • static void park( ):底层是unsafe类native方法
  • static void park(Object blocker)
  • blocker是用来记录线程被阻塞时被谁阻塞的。用于线程监控和分析工具来定位原因的。setBlocker(t, blocker) 方法的作用是记录t线程是被broker阻塞的。

② 唤醒方法(注意这个permit最多只能为1)

调用 unpark(thread) 方法后,就会将 thread 线程的许可 permit设置成1(注意多次调用unpark方法,不会累加,permit值还是1)会自动唤醒thread线程,即之前阻塞中的 LockSupport.park()方法会立即返回。

park, wait, sleep, interrupt, yeild 对比

JVM线程状态: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED

  • BLOCKED:是等待获得对象锁
  • WAITING是调用了:wait, sleep, park

1. 线程让步: yield()

yield() 的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权

  • 但是,并不能保证在当前线程调用 yield() 之后,其它具有相同优先级的线程就一定能获得执行权;
  • 也有可能是当前线程又进入到“运行状态”继续运行!
  • 在操作系统层面让线程从running变成ready状态,等待继续被调度。在jvm的线程状态还是RUNNABLE

2、阻塞线程,并且释放锁: Object中的wait()和notify()

  • 进入 TIMED_WAITING 状态,让出锁,并进入对象的等待
  • 因为wait需释放锁,所以必须在synchronized中使用(没有锁时使用会抛出IllegalMonitorStateException)
  • notify也要在synchronized使用,并且应该指定对象
  • synchronized(),wait(),notify() 对象必须一致,一个synchronized()代码块中只能有1个线程wait()或notify()

3、线程休眠:sleep()

  • sleep() 定义在Thread.java中。
  • sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。
  • sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间;在线程重新被唤醒时,它会由“阻塞状态”变成“就绪状态”,从而等待cpu的调度执行
  • 进入TIMED_WAITING状态,不出让锁

4、LockSupport中的park() 和 unpark()

总结一下,LockSupport比Object的wait/notify有两大优势:

  • LockSupport不需要在同步代码块里 。所以线程间也不需要维护一个共享的同步对象了,实现了线程间的解耦。说明:park和wait的区别。wait让线程阻塞前,必须通过synchronized获取同步锁。
  • unpark函数可以先于park调用,所以不需要担心线程间的执行的先后顺序。
  • park, 进入WAITING状态,对比wait不需要获得锁就可以让线程WAITING,通过unpark唤醒

5. join

等待该线程终止。

  • 等待调用join方法的线程结束,再继续执行。
  • 如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。

yield() 与 wait()的比较

我们知道 ,wait() 的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁 。而yield()的作用是让步,它也会让当前线程离开“运行状态”。它们的区别是:

  • (1) wait() 是让线程由“运行状态”进入到“等待(阻塞)状态”,而不yield()是让线程由“运行状态”进入到“就绪状态”。.
  • (2) wait()是会线程释放它所持有对象的同步锁,而yield()方法不会释放锁

sleep() 与 wait()的比较:

  • 我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而sleep()的作用是也是让当前线程由“运行状态”进入到“休眠(阻塞)状态”。
  • 但是,wait()会释放对象的同步锁,而sleep()则不会释放锁。(sleep 不释放锁的原因,是因为 sleep 中可以传入睡眠时间,时间一到就将该线程加入到就绪队列中,因此不能释放锁,释放锁后重新获得锁的时间不可控)

sleep()与yield()的比较:

sleep和yield的区别在于, sleep可以使优先级低的线程得到执行的机会, 而yield只能使同优先级的线程有执行的机会.

JUC 高并发编程(13):LockSupport 概述, wait 与 sleep与park的区别相关推荐

  1. Java JUC高并发编程(三)-CallableJUC辅助类

    目录 一.Callable接口 二.JUC辅助类 1.减少计数CountDownLatch 2.循环栅栏CyclicBarrier 3.信号灯Semaphore 一.Callable接口 Callab ...

  2. Java JUC高并发编程(一)

    目录 一.概述 二.Lock接口 三.线程间的通信 解决虚假唤醒问题 Lock通信示例: 四.线程间定制化通信 一.概述 JUC就是java.util.concurrent工具包的简称,这是一个处理线 ...

  3. 【JUC高并发编程】—— 初见JUC

    一.JUC 概述 什么是JUC JUC 是 Java并发编程的缩写,指的是 Java.util.concurrent 即Java工具集下的并发编程库 [说白了就是处理线程的工具包] JUC提供了一套并 ...

  4. 详解JUC高并发编程

    JUC并发编程 并发编程的本质:充分利用CPU的资源 问题:JAVA可以开启线程吗? ​ 不能:最底层是本地方法,底层是C++,Java无法直接操作硬件 1.线程里有几个状态 NEW, 新生 RUNN ...

  5. 【JUC高并发编程】—— 再见JUC

    一.读写锁 读写锁概述 1️⃣ 什么是读写锁? 读写锁是一种多线程同步机制,用于在多线程环境中保护共享资源的访问 与互斥锁不同的是,读写锁允许多个线程同时读取共享资源,但在有线程请求写操作时,必须将其 ...

  6. JUC高并发编程从入门到精通(全)

    目录 前言 1. Lock接口 1.1 复习synchronized 1.2 Lock接口 1.3 Lock方法 1.4 两者差异 2. 线程间通信 2.1 synchronized案例 2.2 Lo ...

  7. 高级技术之 JUC 高并发编程

    1,什么是 JUC 1.1 JUC简介 JUC 就是java.util.concurrent 工具包的简称,这一个专门用来处理线程的工具包,JDK1.5开始出现 1.2 进程与线程 **进程(Proc ...

  8. 《尚硅谷高级技术之JUC高并发编程》学习笔记11—— Fork / Join 框架

    文章目录 Fork / Join 框架简介 fork() 方法 join() 方法 Fork / Join 框架的异常处理 入门案例 总结 Fork / Join 框架简介 Fork / Join 它 ...

  9. java线程高并发编程

    java线程详解及高并发编程庖丁解牛 线程概述: 祖宗: 说起java高并发编程,就不得不提起一位老先生Doug Lea,这位老先生可不得了,看看百度百科对他的评价,一点也不为过: 如果IT的历史,是 ...

最新文章

  1. LabVIEW读写各类格式图像的方法(基础篇—1)
  2. Atitit.java c#这类编程语言的设计失败点attilax总结
  3. linux 账号和密码文件 /etc/passwd和/etc/shadow 简介
  4. Visual C# 2010 实现资源管理器
  5. pyecharts运行了但是没有图_新版pyecharts,Python可视化so easy and powerful !
  6. mysql 5.7.13 安装配置方法图文教程(linux)
  7. 信息学奥赛一本通 1043:整数大小比较 | OpenJudge NOI 1.4 05
  8. 用python计算绩点的代码_【Python】计算GPA
  9. [水力建模]EPANET代码解读1
  10. 一图抵千言:带你快速学会 GoogLeNet 神经网络 | CSDN 博文精选
  11. 全网最详细的hive-site.xml配置文件里如何添加达到Hive与HBase的集成,即Hive通过这些参数去连接HBase(图文详解)...
  12. 服务器位置设置,服务器部署位置
  13. 如何利用JClassLib修改.class文件
  14. python实现抠图_python和opencv实现抠图
  15. wince 德赛西威2413_德赛西威NAV230凯立德2016春季专版C2134-C7M07-3921J0S
  16. 冀教版小学三年级上册计算机教案,冀教版小学三年级上册信息技术教案三篇
  17. Visual Studio2022编译报错解决方法
  18. 用Bittorrent和PHP搭建BT Tracker服务器和发布页
  19. 全球知名的人工智能研究院(实验室)
  20. css布局——GFC

热门文章

  1. 微信小程序层叠轮播图、3D轮播图
  2. 我的世界手机有PHP的开服器下载,《我的世界手机版》怎么用电脑开服,pocketminePC版使用教程...
  3. 【git】Git删除本地分支和删除远程分支
  4. 产品设计在生活中——设计与生产的关系(3)
  5. 远程桌面连接:出现身份验证错误,要求的函数不受支持报错,解决方法
  6. 函数计算乘积python multi_两个函数的乘积
  7. 阿里无线11.11 | 手机淘宝移动端接入网关基础架构演进之路
  8. 全球与中国厨房除油剂市场现状及未来发展趋势
  9. 最新iApp影视解析源码+实测可用
  10. IDEA中使用git提交代码