线程是如何通讯的?【Object Conditon LockSupport】

2024-01-06 21:04

本文主要是介绍线程是如何通讯的?【Object Conditon LockSupport】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

线程是如何通讯的?

    • 一、Object 类下的 wait()、notify() 和 notifyAll) 方法方法说明:
    • 二、Condition 类下的 await()、signal() 和 signalAll() 方法方法说明:
    • 三、LockSupport 下的 park() 和 unpark() 方法

线程等待和通知机制就是线程通讯的主要手段
在 Java 中,线程通讯的实现方法主要有以下几种:

  1. Object 类下的 wait()、notify() 和 notifyAll() 方法
  2. Condition 类下的 await()、 signal() 和 signalAll() 方法
  3. LockSupport 类下的 park()和 unpark() 方法

一、Object 类下的 wait()、notify() 和 notifyAll) 方法方法说明:

  1. wait(): 让当前线程处于等待状态,并释放当前拥有的锁
  2. notify(): 随机唤醒等待该锁的其他线程,重新获取锁,并执行后续的流程,只能唤醒一个线程
  3. notifyAll(): 唤醒所有等待该锁的线程(锁只有一把,虽然所有线程被唤醒,但所有线程需要排队执行)。
class ObjectCommunicate {public static void main(String[] args) throws InterruptedException {Object lock = new Object();// 创建线程并执行new Thread(() -> {System.out.println("线程1: 开始执行");synchronized (lock) {try {System.out.println("线程1: 进入等待");lock.wait();System.out.println("线程1: 继续执行");Thread.sleep(300);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("线程1: 执行完成");}}).start();Thread.sleep(1090);synchronized (lock) {// 唤醒线程System.out.println("执行 notifyAl1()");lock.notifyAll();}}
}

二、Condition 类下的 await()、signal() 和 signalAll() 方法方法说明:

  1. await(): 对应 Object 的 wait() 方法,线程等待;
  2. signal(): 对应 Object 的 notify() 方法,随机唤醒一个线程
  3. signalAll(): 对应 Object 的 notifyAll() 方法,唤醒所有线程。
class ConditionCommunicate {public static void main(String[] args) {Lock lock = new ReentrantLock();Condition condition = lock.newCondition();Condition condition2 = lock.newCondition();lock.lock();try {condition.await();condition.signal();} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}
}

三、LockSupport 下的 park() 和 unpark() 方法

方法说明:

  1. LockSupport.park(): 休眠当前线程
  2. LockSupport.unpark(线程对象): 唤醒某一个指定的线程

PS: LockSupport 无需配锁 (synchronized 或 Lock) 一起使用。

class LockSupportCommunicate {public static void main(String[] args) {Thread t1 = new Thread(() -> {LockSupport.park();System.out.println("线程1");},"线程1");t1.start();Thread t2 = new Thread(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("唤醒线程1");LockSupport.unpark(t1);},"线程2");t2.start();}
}

为什么一个线程等待和唤醒的功能需要这么多的实现呢?

  1. LockSupport 必要性: 前两种方法 notify 方法以及 signal 方法都是随机唤醒,如果存在多个等待线程的话,可能会唤醒不应该唤醒的线程,因此有 LockSupport 类下的 park 和 unpark 方法指定唤醒线程是非常有必要的
  2. Condition 必要性: Condition 相比于 Object 类的 wait 和 notify/notifyAll 方法,前者可以创建多个等待集:防止生产者唤醒生产者,让生产者只能唤醒消费者 这样才好

Condition 能实现的功能,Obiect 却不能实现,这就是 Condition 类存在的必要性。那问题来了,为什么还有会 Object 的 wait 和 notify 方法呢?因为 Object 类诞生的比较早,也就是说 Condition 和 Locksupport 都是 JDK 后期版本才出现的功能,所以就有了现在这么多线程唤醒和等待的方法了。

这篇关于线程是如何通讯的?【Object Conditon LockSupport】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/577601

相关文章

Java中如何正确的停掉线程

《Java中如何正确的停掉线程》Java通过interrupt()通知线程停止而非强制,确保线程自主处理中断,避免数据损坏,线程池的shutdown()等待任务完成,shutdownNow()强制中断... 目录为什么不强制停止为什么 Java 不提供强制停止线程的能力呢?如何用interrupt停止线程s

python 线程池顺序执行的方法实现

《python线程池顺序执行的方法实现》在Python中,线程池默认是并发执行任务的,但若需要实现任务的顺序执行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录方案一:强制单线程(伪顺序执行)方案二:按提交顺序获取结果方案三:任务间依赖控制方案四:队列顺序消

SpringBoot实现虚拟线程的方案

《SpringBoot实现虚拟线程的方案》Java19引入虚拟线程,本文就来介绍一下SpringBoot实现虚拟线程的方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录什么是虚拟线程虚拟线程和普通线程的区别SpringBoot使用虚拟线程配置@Async性能对比H

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Java中的xxl-job调度器线程池工作机制

《Java中的xxl-job调度器线程池工作机制》xxl-job通过快慢线程池分离短时与长时任务,动态降级超时任务至慢池,结合异步触发和资源隔离机制,提升高频调度的性能与稳定性,支撑高并发场景下的可靠... 目录⚙️ 一、调度器线程池的核心设计 二、线程池的工作流程 三、线程池配置参数与优化 四、总结:线程

我们来说说Java LockSupport 的 park 和 unpark

《我们来说说JavaLockSupport的park和unpark》LockSupport是JDK底层线程阻塞工具,通过park/unpark实现线程阻塞与唤醒,避免死锁,与Object的w... 目录一、LockSupport1.1、LockSupport函数列表1.2、基本使用先 park 再 unpa

Python错误AttributeError: 'NoneType' object has no attribute问题的彻底解决方法

《Python错误AttributeError:NoneTypeobjecthasnoattribute问题的彻底解决方法》在Python项目开发和调试过程中,经常会碰到这样一个异常信息... 目录问题背景与概述错误解读:AttributeError: 'NoneType' object has no at

WinForm跨线程访问UI及UI卡死的解决方案

《WinForm跨线程访问UI及UI卡死的解决方案》在WinForm开发过程中,跨线程访问UI控件和界面卡死是常见的技术难题,由于Windows窗体应用程序的UI控件默认只能在主线程(UI线程)上操作... 目录前言正文案例1:直接线程操作(无UI访问)案例2:BeginInvoke访问UI(错误用法)案例

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.