线程中的join()、wait() 和 notify()详解及练习题

一、join()

Thread提供了 join() 方法,用于等待当前线程所调用的其他线程执行完毕。

1、当一个线程调用另一个线程的 join() 方法时,它会被阻塞,直到被调用的线程执行完毕或达到指定的超时时间。

比如:当主线程main中调用了另一个线程thread1,那么main线程会被阻塞,只有当thread1执行完毕,main线程才继续执行。

2、当然也可以调用join() 方法还有一个重载的形式,允许指定等待的最大时间:

public final synchronized void join(long millis) throws InterruptedException

在上述形式中,millis 参数表示等待的最大时间,以毫秒为单位。如果被调用的线程在指定的时间内没有执行完毕,当前线程将不再等待,继续执行后续的操作。

join() 方法通常用于实现线程之间的协作和同步。例如,可以创建多个线程,然后使用 join() 方法来确保这些线程按照特定的顺序执行。

练习1:要求线程a执行完才开始线程b, 线程b执行完才开始线程c

import org.junit.Test;/*** @Author xpf* @Date 2023/9/5 17:07* @Version 1.0*  要求线程a执行完才开始线程b, 线程b执行完才开始线程c*/
public class MyThreadJoin {public static class MyThread extends Thread{MyThread(String name){super(name);}@Overridepublic void run() {for (int i= 1; i <= 10; i++){System.out.println(getName() + ":" + i);}}}//https://blog.csdn.net/shinecjj/article/details/103792151public static void main(String[] args) {MyThread t1 = new MyThread("a");MyThread t2 = new MyThread("b");MyThread t3 = new MyThread("c");try {t1.start();t1.join();t2.start();t2.join();t3.start();t3.join();} catch (InterruptedException e) {e.printStackTrace();}}}

结果:

二、wait() 和 notify()

1、wait() 和 notify() 是object对象的方法

2、wait():

可以使当前线程进入等待状态直到其他线程调用 notify() 或者 notifyAll() 方法唤醒它。

在调用 wait() 方法时,当前线程会释放它所持有的锁,以便其他线程可以访问共享资源

 3、notify():

用于唤醒一个处于等待状态的线程,如果有多个线程在等待,则只会唤醒其中一个线程

notifyAll() 方法则会唤醒所有处于等待状态的线程。 

wait和 notify 方法必须在同步块中使用,即在使用这两个方法的对象上获取锁。否则会抛出illegalMonitorStateException异常

练习1:两个线程轮流打印数字,一直到100

/*** @Author xpf* @Date 2023/9/6 10:35* @Version 1.0* 2、两个线程轮流打印数字,一直到100* wait() 和 notify() 是object对象的方法* wait():可以使当前线程进入等待状态,直到其他线程调用 notify() 或者 notifyAll() 方法唤醒它。*         在调用 wait() 方法时,当前线程会释放它所持有的锁,以便其他线程可以访问共享资源* notify():用于唤醒一个处于等待状态的线程,如果有多个线程在等待,则只会唤醒其中一个线程。notifyAll方法则会唤醒所有处于等待状态的线程。* wait和 notify 方法必须在同步块中使用,即在使用这两个方法的对象上获取锁。否则会抛出illegalMonitorStateException异常*/
public class ThreadWaitNotify {static class TakeTurnsAdd{final Object lock = new Object();boolean getFlag = true;int sum = 1;public void add1(){synchronized (lock){String threadName = Thread.currentThread().getName();for (int i = 1; i <= 50; i++) {if (getFlag){try {
//                            System.out.println(threadName + "wait()前" );lock.wait();
//                            System.out.println(threadName + "wait()后" );} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(threadName + "a:" + sum++);
//                    System.out.println(threadName + "notify()前" );getFlag = !getFlag;lock.notify();
//                    System.out.println(threadName + "notify()后" );}}}public void add2(){synchronized (lock){String threadName = Thread.currentThread().getName();for (int i = 1; i <= 50; i++) {if (!getFlag){try {
//                            System.out.println(threadName + "wait()前" );lock.wait();
//                            System.out.println(threadName + "wait()后" );} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(threadName + "b:" + sum++);
//                    System.out.println(threadName + "notify()前" );getFlag = !getFlag;lock.notify();
//                    System.out.println(threadName + "notify()后" );}}}}public static void main(String[] args) {TakeTurnsAdd takeTurnsAdd = new TakeTurnsAdd();new Thread(()->{takeTurnsAdd.add1();}).start();new Thread(()->{takeTurnsAdd.add2();}).start();}
}

结果:

...

 练习2:两线程,一个打印数字从1到52,另一个打印字母从A到Z,输出:12A34B56C...5152Z

/*** @Author xpf* @Date 2023/9/6 10:35* @Version 1.0* 两线程,一个打印数字从1到52,另一个打印字母从A到Z,输出:12A34B56C...5152Z*/
public class ThreadWaitNotify2 {static class TakeTurnsAdd{final Object lock = new Object();boolean getFlag = false;int sum = 1;public void add1(){synchronized (lock){String threadName = Thread.currentThread().getName();for (int i = 1; i <= 26; i++) {if (getFlag){try {
//                            System.out.println(threadName + "wait()前" );lock.wait();
//                            System.out.println(threadName + "wait()后" );} catch (InterruptedException e) {e.printStackTrace();}}System.out.print(sum++);System.out.print(sum++);
//                    System.out.println(threadName + "notify()前" );getFlag = !getFlag;lock.notify();
//                    System.out.println(threadName + "notify()后" );}}}public void add2(){synchronized (lock){String threadName = Thread.currentThread().getName();for (int i = 0; i < 26; i++) {if (!getFlag){try {
//                            System.out.println(threadName + "wait()前" );lock.wait();
//                            System.out.println(threadName + "wait()后" );} catch (InterruptedException e) {e.printStackTrace();}}System.out.print((char) (65+i));
//                    System.out.println(threadName + "notify()前" );getFlag = !getFlag;lock.notify();
//                    System.out.println(threadName + "notify()后" );}}}}public static void main(String[] args) {TakeTurnsAdd takeTurnsAdd = new TakeTurnsAdd();new Thread(()->{takeTurnsAdd.add1();}).start();new Thread(()->{takeTurnsAdd.add2();}).start();}
}

结果:

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

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

相关文章

“搞事情”?OpenAl将于11月召开其首届开发者大会

摘要&#xff1a;OpenAI也要召开它的第一届开发者大会了。这次活动&#xff0c;或许标志着OpenAI向其下一阶段的商业开发迈出了关键一步。 昨天&#xff0c;OpenAI宣布将于11月6日举办其首次开发者大会。在这场名为“OpenAI DevDay”的活动中&#xff0c;OpenAI的技术人员将进行…

白鲸开源 DataOps 平台加速数据分析和大模型构建

作者 | 李晨 编辑 | Debra Chen 数据准备对于推动有效的自助式分析和数据科学实践至关重要。如今&#xff0c;企业大都知道基于数据的决策是成功数字化转型的关键&#xff0c;但要做出有效的决策&#xff0c;只有可信的数据才能提供帮助&#xff0c;随着数据量和数据源的多样…

安防监控/视频存储/视频汇聚平台EasyCVR如何接入智能分析网关V4?

TSINGSEE青犀AI边缘计算网关硬件 —— 智能分析网关目前有5个版本&#xff1a;V1、V2、V3、V4、V5&#xff0c;每个版本都能实现对监控视频的智能识别和分析&#xff0c;支持抓拍、记录、告警等&#xff0c;每个版本在算法模型及性能配置上略有不同。硬件可实现的AI检测包括&am…

SpringMVC框架学习

java 学习笔记指路 基础知识 Python转java补充知识 Java中常见的名词解释 前端 【黑马程序员pink老师前端】HTML 【黑马程序员pink老师前端】JavaScript基础大总结 【黑马程序员pink老师前端】JavaScript函数与作用域 【黑马程序员pink老师前端】JavaScript对象 数据库 【黑马程…

nowcoder NC10 大数乘法

题目链接&#xff1a; https://www.nowcoder.com/practice/c4c488d4d40d4c4e9824c3650f7d5571?tpId196&tqId37177&rp1&ru/exam/company&qru/exam/company&sourceUrl%2Fexam%2Fcompany&difficultyundefined&judgeStatusundefined&tags&tit…

HJ17 坐标移动

Powered by:NEFU AB-IN Link 文章目录 HJ17 坐标移动题意思路代码 HJ17 坐标移动 题意 开发一个坐标计算工具&#xff0c; A表示向左移动&#xff0c;D表示向右移动&#xff0c;W表示向上移动&#xff0c;S表示向下移动。从&#xff08;0,0&#xff09;点开始移动&#xff0c;…

python使用cv2获取截图中的匹配项目的中心位置

在OpenCV中&#xff0c;cv2.matchTemplate()函数用于在大图中查找与小图&#xff08;模板&#xff09;匹配的区域&#xff0c;但并不会直接返回一个区域的box。 想要获取匹配区域的边界框&#xff08;box&#xff09;&#xff0c;以及中心的位置&#xff0c;这样后续好进行自动…

222. 完全二叉树的节点个数

题目链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 我的想法&#xff1a; 递归法 万金油--层次遍历法 当然上面两中都是笨方法&#xff0c;就算不是完全二叉树也能算&#xff0c;没有用到完全二叉树的特性。 我的代码&#xff1…

linux线程讲解

1.线程概述 一个进程在同一时刻只做一件事情&#xff0c;进程是程序执行的一个实例。 线程是操作系统能够进行运算调度的最小单位&#xff0c;一个进程中可以并发多个线程&#xff0c;每条线程并行执行不同的任务。 进程&#xff1a;资源分配的最小单位。线程&#xff0c;程…

50etf期权最多能开仓多少手?

50etf期权限仓限额的操作&#xff0c;是为了能更好防范和控制期权交易的风险&#xff0c;无论是期货还是期权&#xff0c;在交易中都有规定的持仓限额&#xff0c;不能超过某个额度&#xff0c;那么50etf期权最多能开仓多少手&#xff1f;下文为你们全面介绍&#xff01;本文来…

【数据结构】单链表详解

当我们学完顺序表的时候&#xff0c;我们发现了好多问题如下&#xff1a; 中间/头部的插入删除&#xff0c;时间复杂度为O(N)增容需要申请新空间&#xff0c;拷贝数据&#xff0c;释放旧空间。会有不小的消耗。增容一般是呈2倍的增长&#xff0c;势必会有一定的空间浪费。例如当…

纯手工总结超详细关于计算机网络的五层知识点,看看你都掌握了没

纯手工总结超详细关于计算机网络的五层知识点&#xff0c;看看你都掌握了没 文章目录 纯手工总结超详细关于计算机网络的五层知识点&#xff0c;看看你都掌握了没1.应用层1.1 HTTP协议1.1.1 URL1.1.2 HTTP方法1.1.3 HTTP请求1.1.4 HTTP状态码1.1.5 HTTP会话保持 1.2 HTTPS协议 …

Linux上安装FTP

1、登录FTP&#xff0c;执行安装命令 yum -y install vsftpd 2、启动FTP服务器&#xff0c;设置开启自启动 systemctl enable vsftpd.service systemctl start vsftpd.service systemctl status vsftpd.service #查看状态, 显示active说明FTP启动成功 3、修改FTP配置文件/et…

数据通信——传输层TCP(可靠传输机制的滑动窗口)

引言 之前提到过拥塞问题&#xff0c;如果大量数据疯狂涌入&#xff0c;接收端无法及时处理就会导致数据丢包&#xff0c;从而使得通信受到干扰。之前的连续ARQ如果不加以节制&#xff0c;疯狂发送报文&#xff0c;接收端无法及时返回ACK就会导致网络瘫痪。 滑动窗口机制协议 这…

【未写完】笔记本电脑Windows7怎么省电

2023年9月7日&#xff0c;周四晚上 从2022年到2023年9月7日这期间&#xff0c;我断断续续研究了一个月这个问题。 到如今终于有所收获&#xff0c;于是把这些记成一篇博客。 不定期更新&#xff0c;因为最近开学了&#xff0c;比较忙。 首先&#xff0c;根据我的实践&#x…

阿里云部署开源MQTT平台mosquitto的docker操作

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的消息传输协议&#xff0c;广泛用于物联网和传感器网络中。Mosquitto是一个流行的开源MQTT代理&#xff0c;可以在Docker中进行配置和部署。本文将详细介绍如何在Docker中配置Mosquitto MQTT代理…

maven打包时显示无效jdk版本

1、配置当前项目所需的Jdk版本 2、与当前项目指定的jdk版本相同 3、与当前项目指定的jdk版本相同 4、与当前项目指定的jdk版本相同 5、指定主项目启动时的vm配置与当前项目所需版本相同

Stable Diffusion — ControlNet 超详细讲解

Stable Diffusion — ControlNet 超详细讲解 ControlNet 最近非常火&#x1f525;&#xff01;ControlNet 和 Stable Diffusion 的结合使 Stable Diffusion 能够接受指导图像生成过程的条件输入&#xff0c;从而增强了 Stable Diffusion 的性能。今天为大家深入剖析 ControlNe…

算法通关村十四关:白银挑战-堆能高效解决的经典问题

白银挑战-堆能高效解决的经典问题 1.在数组中找第K大的元素 LeetCode215 https://leetcode.cn/problems/kth-largest-element-in-an-array/ 思路分析 主要解决方法有3个&#xff0c;选择法&#xff0c;堆查找法和快速排序法 方法1&#xff1a;选择法 先遍历一遍找到最大的…

如何让自己的精力集中 Maven自学笔记 马云演讲观看

目录 如何让自己的精力集中 Avoid having multiple tasks and objects in your line of sight 人的脑袋是给自己思考用的 晚上床上想千条路&#xff0c;早上起床还是走原路 参与才会变得更好 共度灾难&#xff0c;是需要互相鼓励的 CFO Capital 上海各区都有哪些大学?…