多线程之waitnotify

news2024/11/25 0:57:14

目录:

前言

1.wait()方法

2 notify()方法

3.wait & notify的代码示例:

4.关于notifyAll()方法



前言

线程最大的问题就是抢占式执行,随机调度。虽然线程在操作系统内核里的调度是随机的,但是可以通过一些办法来控制线程之间的执行顺序,让一些线程主动阻塞,主动放弃CPU。

示例:

现在有t1 和t2两个线程,希望t1线程先进行工作,然后工作一段时间后,再让t2线程再来工作。就可以让t2线程先进行wait(阻塞,主动放弃cpu),等t1线程工作一段时间后,再通过notify通知t2线程,把 t2线程唤醒,让 t2线程接着工作。

上述场景,使用join 或者sleep可不可以呢?

使用join,则必须要t1线程彻底执行完,,t2线程才能运行。如果是希望t1线程先做50%的工作,就让t2线程开始执行,使用join是办不到的,因为join要等到一个线程彻底执行完毕。使用sleep,指定一个休眠时间的,但是t1线程执行的这些工作,到底用了多少时间是不确定的。那么是可以使用waitnotify来解决的。其中,wait 需要搭配 synchronized 使用,sleep 不需要;wait 是 Object 的方法 ,sleep 是 Thread 的静态方法。

1.wait()方法

wait要搭配 synchronized 来使用,脱离 synchronized 使用 wait 会直接抛出异常。

wait的操作:

释放当前的锁

使当前执行代码的线程进行阻塞等待

收到通知时被唤醒,重新尝试获取这个锁,在获取锁之后继续往下执行。

wait 结束等待的条件:

其他线程调用该对象的 notify 方法

wait 等待时间超时 (wait 方法提供一个带有 timeout 参数的版本,来指定等待时间)

其他线程调用该等待线程的 interrupted 方法, 导致 wait 抛出 InterruptedException 异常

2 notify()方法

notify的操作:(唤醒等待的线程)

notify()方法是用来通知同一个对象上等待的线程,对其发出通知notify,并使它们重新获取该对象的对象锁。

如果有多个线程等待,则有线程调度器随机挑选出一个呈 wait 状态的线程。

3.wait & notify代码示例:

代码示例1:

public class ThreadDemo16 {
    public static void main(String[] args) throws InterruptedException {
        Object object = new Object();
        Thread t1 = new Thread(()->{
            System.out.println("t1线程等待之前");
            try {
                synchronized (object){
                    object.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("t1线程被唤醒");
        });

        Thread t2 = new Thread(()->{
            System.out.println("t2线程notify之前");
            synchronized (object){
                object.notify();
            }
            System.out.println("t2线程notify之后");
        });

        t1.start();
        Thread.sleep(1000);//这个保证t1线程一定要先进行阻塞等待,t2才能进行唤醒
        t2.start();
    }
}

ae325cf6e05e478b944bbe4b7f5b3e7c.png

代码示例2:三个线程顺序打印ABC

public class ThreadDemo17 {
    public static void main(String[] args) throws InterruptedException {
        Object locker1 = new Object();
        Object locker2 = new Object();

        Thread t1 = new Thread(()->{
            System.out.println("A");
            synchronized (locker1){
                locker1.notify();
            }
        });

        Thread t2 = new Thread(()->{
            try {
                synchronized (locker1){
                    locker1.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("B");

            synchronized (locker2){
                locker2.notify();
            }
        });

        Thread t3 = new Thread(()->{
            try {
                synchronized (locker2){
                    locker2.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("C");
        });
        t2.start();
        t3.start();
        Thread.sleep(1000);//保证t2和t3先执行了,先进行等待
        t1.start();
    }
}

 ebadb8f792e34f7db925d6b94a0e13d1.png

 4.关于notifyAll()方法

notifyAll和notify是非常相似的,当多个线程wait 的时候, notify随机唤醒一个, notifyAll所有线程都唤醒,这些线程再来一起竞争锁。

 

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

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

相关文章

带你了解SVG标签

✍️ 作者简介: 前端新手学习中。 💂 作者主页: 在主页中查看更多前端教学,可接大学生前端作业单。 🎓 专栏分享:css重难点教学 Node.js教学 从头开始学习 ajax学习 js学习 目录初始SVG矩形,圆形和椭圆型 矩形 圆…

云安全(云安全数据中心、WAF、DDOS)

安全 安全威胁 可用性 安全威胁:大规模分布式拒绝服务攻击(DDoS)、僵尸网络(Botnet) 影响:网站业务不可用 完整性 安全威胁:网站入侵、服务器口令暴力破解 影响:网站页面被篡改和植入后门 保密性 安全威胁:网站后门…

二、Groovy入门

文章目录二、Groovy入门2.1 Groovy 简介2.2 Groovy 安装[非必须]2.3 IDEA创建 Groovy 项目2.4 Groovy 基本语法2.4.1 案例 1:基本注意点2.4.2 案例 2:引号说明2.4.3 案例 3:三个语句结构2.4.4 案例 4:类型及权限修饰符2.4.5 案例 5:集合操作2.4.6 案例 6:类导入2.4.7 案例 7:异…

MySQL是怎么保证主备一致的?

在前面的文章中,我不止一次地和你提到了 binlog,大家知道 binlog 可以用来归档,也可以用来做主备同步,但它的内容是什么样的呢?为什么备库执行了 binlog 就可以跟主库保持一致了呢?今天我就正式地和你介绍一下它。 毫不夸张地说,MySQL 能够成为现下最流行的开源数据库,…

pytorch torchvision.ops.roi_align

pytorch的torchvision.ops.roi_align这个算子真的是坑我好多天啊!害我连续加班半个月!二阶段目标检测后面用roi_align来提取特征。 接口官方说明:https://pytorch.org/vision/stable/generated/torchvision.ops.roi_align.html?highlightroi…

React Devtools 使用技巧

首先在扩展迷中搜索下载该扩展,引入到 Chrome 的扩展程序中。 当我们添加扩展到Chrome中,就会在浏览器中看到 React Devtools 的 Icon,同时通过该扩展我们就可以知道当前打开的网站是开发环境的网站还是生产环境,React Devtools …

Mysql 安装 ubutu20.04

Mysql 安装 1:sudo apt-get autoremove --purge mysql* 2:sudo apt-get install mysql-server 3:sudo apt --fix-broken install -y 4:sudo apt-get install mysql-server 5: service mysql status 5:sudo…

C++STL-stackqueuepriority_queue介绍

文章目录1. 容器适配器1.1 什么是适配器1.2 STL标准库中stack和queue的底层结构2. stack的介绍和使用2.1 stack的介绍2.2 stack的使用3. queue的介绍和使用3.1 queue的介绍3.2 queue的使用4. priority_queue的介绍和使用4.1 priority_queue的介绍4.2 priority_queue的使用1. 容…

年度征文 | 回顾2022,展望2023

目录 一、前言 二、回顾2022 三、展望2023 个人主页: ζ小菜鸡大家好我是ζ小菜鸡,感谢大家一直的支持。岁末年初,让我们一起回顾2022展望2023。一、前言 时光荏苒,岁月如梭,2022 已和我们再见,2023 正向我们走来。…

云原生周刊 | 在 Grafana 中显示 K8s Service 之间的依赖关系

开源项目推荐 Caretta 这个项目可以在 Grafana 监控面板中显示 K8s Service 之间的依赖关系。底层使用的是 eBPF,对应用无侵入。 busuanzi 这是一个基于 Golang Redis 的简易访问量统计系统,可以用来替代不蒜子。 vim-online-editor 这是一个在线版…

一文读懂 Kubernetes 存储设计

在 Docker 的设计中,容器内的文件是临时存放的,并且随着容器的删除,容器内部的数据也会一同被清空。不过,我们可以通过在 docker run 启动容器时,使用 --volume/-v 参数来指定挂载卷,这样就能够将容器内部的…

企业级数据中台构建方法和指导

目录1. 数据中台的概念2. 数据中台适合企业2.1 企业构建数据中台面临的问题2.2 企业构建数据中台解决问题的方法2.3 什么样的企业适合构建数据中台3. 如何建设数据中台3.1 方法论3.1.1 OneData3.1.2 OneService3.2 技术3.3 组织4. 数据中台实现:指标管理5. 数据中台…

高速缓存伪共享(false sharing)

0. CPU缓存 根据摩尔定律:芯片中的晶体管数量每隔18个月就会翻一番。导致CPU的性能和处理速度变得越来越快,而提升CPU的运行速度比提升内存的运行速度要容易和便宜的多,所以就导致了CPU与内存之间的速度差距越来越大。 为了弥补CPU与内存之间…

错失搭档张云雷,杨九郎和郭冬临一起演小品

熟悉相声的人都知道,这个传统的曲艺行业,一般是由捧哏和逗哏组成,两个人相辅相成缺一不可。就拿德云社的相声演员来说,也产生了很多对优秀演员,比如说郭德纲和于谦,比如说岳云鹏和孙越等等。 除了这两对相声…

微信开放平台之小程序获取用户信息

说实话,微信开放平台的文档真的是狗屎一般的存在,维护不及时,混乱,每隔一段时间更新一次授权接口!着实让开发者想口吐芬芳了!文档内跳来跳去,找不到一个完整的链路!维护好几套接口文…

_Linux多线程-线程控制篇

文章目录1. POSIX线程库2. 创建线程3. 线程ID及进程地址空间布局4. 线程等待5. 线程终止pthread_ exitpthread_ cancel6. 分离线程7. 总结1. POSIX线程库 与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_”打头的要使用这些函数库&#…

三角函数在编程中的实际运用—永劫无间脚本

三角函数在编程中的实际运用—永劫无间脚本前言需求思路代码■ 转义码■ 源码具体讲解三角函数计算相对移动求余跳过不需要的位置成品最后前言 义务教育下,年轻人从初中就开始学三角函数却半辈子也没用上,除了特殊行业,做开发的可能也就大学…

Nginx web服务器入门及其在Linux中的搭建

目录 ​编辑 一、Nginx基本概述 1.介绍 2.优点 3.应用场景 (1)负载均衡 (2)代理缓存 (3)静态资源 (4)安全应用场景 4.Nginx的组成 (1)Nginx二进制…

Canal同步数据

canal同步数据 canal可以用来监控数据库数据的变化,从而获得新增数据,或者修改的数据。 canal是应阿里巴巴存在杭州和美国的双机房部署,存在跨机房同步的业务需求而提出的。 阿里系公司开始逐步的尝试基于数据库的日志解析,获取…

(9)Qt中信号与槽重载的解决方案

信号与槽重载的解决方案 一、通过函数指针解决 //信号 void (Me::*funchungury)() &Me::hungury; void (Me::*funchungury_QString)(QString) &Me::hungury; //槽 void (Me::*funceat)() &Me::eat; void (Me::*funceat_QString)(QString) &Me::eat;//有参…