Java线程等待、唤醒通信机制详解(下)

简介: Java线程等待、唤醒通信机制详解(下)

4 线程协作(JDK API)

细分为: suspend/resume 、 wait/notify、 park/unpark

JDK中对于需要多线程协作完成某一任务的场景,提供了对应API支持。

多线程协作的典型场景是:生产者-消费者模型。(线程阻塞、 线程唤醒)

示例

  • 线程-1去买包子,没有包子,则不再执行
  • 线程-2生产出包子,通知线程-1继续执行

image.png

4.1 suspend、resume(废弃)

  • 调用suspend挂起目标线程
  • resume恢复线程执行

image.png

但该组合很容易写出

死锁

  • 同步代码中使用

1.png

image.png

先后顺序:suspend比resume后执行

1.png

image.png

  • 所以用如下机制替代

4.2 wait/notify

这些方法只能由同一对象锁的持有者线程调用,即写在同步块里!否则抛IllegalMonitorStateException。


wait 方法导致当前线程等待,加入该对象的等待集合中,并且放弃当前持有的对象锁。


notify/notifyAll 方法唤醒一个/所有正在等待这个对象锁的线程。

虽然wait会自动解锁,但对顺序有要求。若在notify被调用后, 才调用wait,则线程会永远处于WAITING态。


正常使用

1.png

死锁

1.png

image.png

synchronized 或 lock

线程先要获得并持有锁,必须在锁块(synchronized或lock)中。必须要先等待后唤醒,线程才能够被唤醒。

park/unpark

LockSupport用来创建锁和其他同步类的基本线程阻塞原语:

  • 线程调用LockSupport.park,则等待“许可”
  • 线程调用LockSupport.unpark,必须把等待获得许可的线程作为参数进行传递,好让此线程继续运行,为指定线程提供“许可(permit)”


不要求park和unpark方法的调用顺序,无需写在任何同步代码块里。

多次调用unpark之后,再调用park,线程会直接运行,不会叠加,累加上限只有 1,即连续多次调用park,第一次会拿到“许可”直接运行,后续调用还是会进入等待。


正常

image.png

死锁

1.png

5 伪唤醒

之前代码中用if语句来判断,是否进入等待状态,是错误的

官方推荐应该在循环中检查等待条件,因为处于等待状态的线程可能会收到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就可能在没有满足结束条件的情况下退出。

伪唤醒是指线程并非因为notify、notifyall、 unpark等API调用而唤醒,而是更底层原因导致的。


image.png


目录
相关文章
|
19天前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
84 1
|
19天前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
72 1
|
1月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
98 0
|
1月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
140 16
|
2月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
2月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
3月前
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
323 83
|
3月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
161 0
|
3月前
|
人工智能 前端开发 安全
Java开发不可不知的秘密:类加载器实现机制
类加载器是Java中负责动态加载类到JVM的组件,理解其工作原理对开发复杂应用至关重要。本文详解类加载过程、双亲委派模型及常见类加载器,并介绍自定义类加载器的实现与应用场景。
208 4