并发编程学习(四):wait()、nitify()

news2025/1/14 18:34:59

1、wait、notify原理 

  •  Owner 线程发现条件不满足,调用wait()方法,即可进入WaitSet,变为WAITING 状态。
  • BLOCKED和WAITING的线程都处于阻塞状态,不占用CPU时间片。
  • BLOCKED线程会在Owner线程释放锁时唤醒。
  • WAITING线程会在Owner线程调用notify()或 notifyAll()时唤醒,但唤醒后并不意味着立刻获得锁,仍需进入EntryList重新竞争。

2、API介绍 

线程通信:wait() / notify() / notifyAll() 此三个方法定义在Object类中的。
  • obj.wait() 让进入object监视器的线程 到waitset等待。
  • obj.notify()在object上正在waitSet等待的线程挑一个唤醒。
  • obj.notifyAll()让object上正在waitSet等待的线程全部唤醒。

它们都是线程之间进行协作的手段,都属于Object对象的方法。必须获得此对象obj的锁,才能调用这几个方法

wait() 方法会释放对象的锁,进入WaitSet等待区(无限制等待,直到notify为止),从而然其他线程有机会获取到对象锁。

wait(long n)有时限的等待,到n毫秒后结束等待,或是被notify。 

未获得锁,直接调用wait()会报错。代码示例:

notify() / notifyAll()代码示例如下:

    final static Object obj = new Object();

    public static void main(String[] args) {

        new Thread(() -> {
            synchronized(obj) {
                log.debug("执行...");
                try {
                    obj.wait(); // 让线程在obj上一直等待下去
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("其它代码...");
            }

        },"t1").start();

        new Thread(() -> {
            synchronized(obj) {
                log.debug("执行...");
                try {
                    obj.wait(); // 让线程在obj上一直等待下去
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("其它代码...");
            }

        },"t2").start();

        // 主线程两秒后执行
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.debug("唤醒obj上的其它线程");
        synchronized (obj) {
//            obj.notify(); // 唤醒obj上随机一个线程
            obj.notifyAll(); // 唤醒obj上所有等待线程
        }

    }

obj.notify()代码执行结果:

14:15:50.663 [t1] DEBUG com.example.common.MagicNumberUtilsTests - 执行...
14:15:50.663 [t2] DEBUG com.example.common.MagicNumberUtilsTests - 执行...
14:15:52.673 [main] DEBUG com.example.common.MagicNumberUtilsTests - 唤醒obj上的其它线程
14:15:52.673 [t1] DEBUG com.example.common.MagicNumberUtilsTests - 其它代码...

obj.notifyAll()代码执行结果:

14:09:31.945 [t1] DEBUG com.example.common.MagicNumberUtilsTests - 执行...
14:09:31.949 [t2] DEBUG com.example.common.MagicNumberUtilsTests - 执行...
14:09:33.959 [main] DEBUG com.example.common.MagicNumberUtilsTests - 唤醒obj上的其它线程
14:09:33.959 [t2] DEBUG com.example.common.MagicNumberUtilsTests - 其它代码...
14:09:33.959 [t1] DEBUG com.example.common.MagicNumberUtilsTests - 其它代码...        

3、wait、notify的正确使用 

3.1、sleep(long n) 和wait(long n) 的区别

  1. sleep是Thread中的静态方法;而wait是Object中的方法。
  2. sleep不需要强制和synchronized配合使用;但wait需要和synchronized一起使用。
  3. sleep在睡眠的同时,不会释放对象锁;但wait在等待的时候会释放对象锁。
  4. 都调用这两个方法后,调用的当前线程都会进入:TIMED_WAITING状态。

3.2、正确使用格式

   final static Object lock = new Object();

// 干活线程
synchronized(lock) {
    while(条件不成立) {
        lock.wait();
    }
    // 干活
}

// 另一个线程
synchronized(lock) {
    lock.notifyAll();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110105.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据库】简答题知识点

数据库系统的结构 数据库系统的逻辑结构可以分为用户级、概念级和物理级三个层次。每个层次的数据库都有自身对数据进行逻辑描述的模式,分另称为外模式、概念模式和内模式。 外模式:是与和具体的应用或者项目有关的逻辑表示,用户可以操作的…

【Proteus仿真】【51单片机】自动浇花灌溉系统设计

文章目录一、功能简介二、软件设计三、实验现象联系作者一、功能简介 本项目使用Proteus8仿真51单片机控制器,使用LCD1602液晶、按键、DS18B20、PCF8591 ADC、土壤湿度传感器、水位传感器、蜂鸣器模块等。 系统运行后,LCD1602显示传感器检测的温度、湿…

【Linux操作系统】多线程(一)

文章目录1. 线程概念2. 线程控制2.1 创建线程2.2 线程ID2.3 线程等待2.4 线程终止2.5 线程分离3. 线程同互斥与同步3.1 互斥量3.2 死锁3.3 同步-条件变量3.4 生产者消费者模型3.5 POSIX信号量3.6 基于环形队列的生产消费者模型1. 线程概念 线程:是在进程内部运行的…

解决资源消耗,top的运用记录

第一条命令uptime load average 后面的三个数字,分别代表1分钟、5分钟和15分钟内机器的平均负载 使用top命令解决负载问题 Cpu(s)这一行提供了CPU运行情况信息 这些缩写分别代表了不同含义 (1)us:用户CPU时间 运行非优雅的用户进程所占CPU时间的百…

离线下载NLTK依赖包([WinError 10061] 由于目标计算机积极拒绝,无法连接)的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…

房产管理系统CAD图形管理应用有哪些?

数图互通房产管理 数图互通房产管理系统建设涵盖学校所有房屋资源管理业务以及CAD图纸的管理,对不同类型的房屋实现相应的业务子系统,实现完善、高效、可溯的房屋资源业务管理,保证数据的完整性、一致性和精确性,及业务的。 通过…

向内而生 向远而行 | 希尔贝壳荣获“2022年度最具投资价值创新企业”奖

12月22日,以“向内而生 向远而行”为主题的2022年度猎云网创投奖项评选正式落下帷幕,各项榜单评选结果正式发布。希尔贝壳凭借先进的技术创新能力获评“2022年度最具投资价值创新企业”奖。 获奖理由 北京希尔贝壳科技有限公司成立于2017年,…

可视化 相机pose或者 pose视锥

可视化 相机pose或者 pose视锥 https://www.camcalib.io/post/visualizing-camera-calibration-results https://bitbucket.org/iviso/camcalib_multiview_pointcloud_example/src/master/ https://bitbucket.org/iviso/ 其他: https://towardsdatascience.com/c…

快速部署PHP Web环境(nginx php mysql redis)

先看最终效果,如下: 它是什么? 它是 docker 容器虚拟化技术。总共只有几KB大小的描述文件,文件里定义了要安装什么、配置什么,一执行就全自动处理好了。 它有什么用? 解决新来同事搭环境搭半天的问题解…

矽昌-- Station 模式支持

Station 模式支持 1. 修改配置 ​ 在/etc/config/wireless中增加一段即可,实例如下: config wifi-ifaceoption key 12345678option ifname sfi0option network wwanoption encryption psk2ccmpoption device radio0option mode staoption bssid A8:5A:…

玩以太坊链上项目的必备技能(修改器 [modifier]-Solidity之旅十五)

修改器(modifier) 在讲修改器(modifier)之前,我们使用前面几篇文章所学到的知识来实现一个简单的 token 类合约。 // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0;contract InheritanceModifierExampl…

Python获取与处理文件路径/目录路径

这里写目录标题文件目录结构说明一、路径获取1.1 获取当前文件的绝对路径1.2.1 获取当前文件的所在目录1.2.2 获取当前文件的所在目录的上一级目录1.3 获取当前文件名1.4 获取当前文件对于基准路径的相对路径二、路径判断2.1 判断路径是否存在2.2 判断路径是否为绝对路径2.3 判…

【Python】matplotlib.axes.Axes.pie()实例讲解

目录:matplotlib.axes.Axes.pie函数实力讲解一、前言二、matplotlib.axes.Axes.pie()函数三、代码示例四、get_cmap函数一、前言 本文章向大家介绍Python matplotlib.axes.Axes.pie()实例讲解,主要分析其语法、参数、返回值和注意事项,并结合…

WorkPlus助力中交四航局打造数字化管理新模式,释放企业生产力

企业简介 中交四航局正式创立于1951年,集团主要从事海内外港口、公路、桥梁、铁路、市政工程、水利工程等大型基础设施建设,以及相关的投资、勘察设计、科研、工业造船和房地产业务。始终致力于“让世界更畅通,让城市更宜居,让生…

logger记录在控制台显示,但是在日志输出文件中不显示问题排查

场景: 代码中存在使用logger.info输出数据到指定的文件中,然后用logstash去收集需要的数据插入到es中。 现象: logger.info输出的记录打断点在控制台上显示,但是在配置的日志输出文件中却找不到日志输出的内容。 log4j配置 如下…

ELK搜索学习笔记--Day1

ELK搜索学习笔记–Day1 1. 课程简介 1.1 课程内容 ELK是包含但不限于Elasticsearch(简称es)、Logstash、Kibana 三个开源软件的组成的一个整体。这三个软件合成ELK。是用于数据抽取(Logstash)、搜索分析&#xff08…

Freemodbus启动流程分析

近项目有用到modbus协议,于是在网上找了些资料成功将freemodbus移植到m3,由于移植过程较简单,网上教程也很多,这里我们就不再赘述.我用到的freemodbus版本是V1.5,下面附上新的源码下载地址:http://www.freemodbus.org/index.php?idx5 下面开始分析下freemodbus得启动流程,老规…

Android设计模式详解之解释器模式

前言 解释器模式是一种使用较少的行为型模式; 提供了一种解释语言的语法或表达式的方式,通过该接口解释一个特定的上下文。 定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表…

MySQL面试常问问题(高可用/性能 + 运维) —— 赶快收藏

1.数据库读写分离了解吗? 读写分离的基本原理是将数据库读写操作分散到不同的节点上,下面是基本架构图: 读写分离 读写分离的基本实现是: 数据库服务器搭建主从集群,一主一从、一主多从都可以。 数据库主机负责读写操作&#x…

洛谷——P1573 栈的操作

文章目录栈的操作题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示AC代码栈的操作 题目描述 现在有四个栈,其中前三个为空,第四个栈从栈顶到栈底分别为 1,2,3,⋯,n1,2,3,\cdots ,n1,2,3,⋯,n。每一个栈只支持一种操作:弹出并压入…