Thread.join()详解

ESP32 BLE Mesh Provisioner实战:手把手教你用ESP-IDF配网智能灯泡(附常见错误排查) 本文提供了一份基于ESP-IDF的ESP32 BLE Mesh Provisioner实战指南,详细解析了配网器的核心角色与工作流程。文章手把手教你从工程搭建、代码初始化到核心回调解析,并重点针对常见的‘Model not bound to AppKey’等错误提供了深度排查思路与解决方案,帮助你构建一个稳定可靠的智能照明网关。 阅读详情

一、使用方式。

join是Thread类的一个方法,启动线程后直接调用,例如:

[java]  view plain  copy
  1. Thread t = new AThread(); t.start(); t.join();  

二、为什么要用join()方法

在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。

三、join方法的作用

在JDk的API里对于join()方法是:

join

public final void join() throws InterruptedException Waits for this thread to die. Throws: InterruptedException  - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

即join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。

四、用实例来理解

写一个简单的例子来看一下join()的用法:

1.AThread 类

  1. BThread类

  2. TestDemo 类

    [java]  view plain  copy
    1. class BThread extends Thread {  
    2.     public BThread() {  
    3.         super("[BThread] Thread");  
    4.     };  
    5.     public void run() {  
    6.         String threadName = Thread.currentThread().getName();  
    7.         System.out.println(threadName + " start.");  
    8.         try {  
    9.             for (int i = 0; i < 5; i++) {  
    10.                 System.out.println(threadName + " loop at " + i);  
    11.                 Thread.sleep(1000);  
    12.             }  
    13.             System.out.println(threadName + " end.");  
    14.         } catch (Exception e) {  
    15.             System.out.println("Exception from " + threadName + ".run");  
    16.         }  
    17.     }  
    18. }  
    19. class AThread extends Thread {  
    20.     BThread bt;  
    21.     public AThread(BThread bt) {  
    22.         super("[AThread] Thread");  
    23.         this.bt = bt;  
    24.     }  
    25.     public void run() {  
    26.         String threadName = Thread.currentThread().getName();  
    27.         System.out.println(threadName + " start.");  
    28.         try {  
    29.             bt.join();  
    30.             System.out.println(threadName + " end.");  
    31.         } catch (Exception e) {  
    32.             System.out.println("Exception from " + threadName + ".run");  
    33.         }  
    34.     }  
    35. }  
    36. public class TestDemo {  
    37.     public static void main(String[] args) {  
    38.         String threadName = Thread.currentThread().getName();  
    39.         System.out.println(threadName + " start.");  
    40.         BThread bt = new BThread();  
    41.         AThread at = new AThread(bt);  
    42.         try {  
    43.             bt.start();  
    44.             Thread.sleep(2000);  
    45.             at.start();  
    46.             at.join();  
    47.         } catch (Exception e) {  
    48.             System.out.println("Exception from main");  
    49.         }  
    50.         System.out.println(threadName + " end!");  
    51.     }  
    52. }  

    打印结果:

    main start.    //主线程起动,因为调用了at.join(),要等到at结束了,此线程才能向下执行。 
    [BThread] Thread start. 
    [BThread] Thread loop at 0 
    [BThread] Thread loop at 1 
    [AThread] Thread start.    //线程at启动,因为调用bt.join(),等到bt结束了才向下执行。 
    [BThread] Thread loop at 2 
    [BThread] Thread loop at 3 
    [BThread] Thread loop at 4 
    [BThread] Thread end. 
    [AThread] Thread end.    // 线程AThread在bt.join();阻塞处起动,向下继续执行的结果 
    main end!      //线程AThread结束,此线程在at.join();阻塞处起动,向下继续执行的结果。
    修改一下代码:
    [java]  view plain  copy
    1. public class TestDemo {  
    2.     public static void main(String[] args) {  
    3.         String threadName = Thread.currentThread().getName();  
    4.         System.out.println(threadName + " start.");  
    5.         BThread bt = new BThread();  
    6.         AThread at = new AThread(bt);  
    7.         try {  
    8.             bt.start();  
    9.             Thread.sleep(2000);  
    10.             at.start();  
    11.             //at.join(); //在此处注释掉对join()的调用  
    12.         } catch (Exception e) {  
    13.             System.out.println("Exception from main");  
    14.         }  
    15.         System.out.println(threadName + " end!");  
    16.     }  
    17. }  

    打印结果:

    main start.    // 主线程起动,因为Thread.sleep(2000),主线程没有马上结束;
    
    [BThread] Thread start.    //线程BThread起动
    [BThread] Thread loop at 0
    [BThread] Thread loop at 1
    main end!   // 在sleep两秒后主线程结束,AThread执行的bt.join();并不会影响到主线程。
    [AThread] Thread start.    //线程at起动,因为调用了bt.join(),等到bt结束了,此线程才向下执行。
    [BThread] Thread loop at 2
    [BThread] Thread loop at 3
    [BThread] Thread loop at 4
    [BThread] Thread end.    //线程BThread结束了
    [AThread] Thread end.    // 线程AThread在bt.join();阻塞处起动,向下继续执行的结果

    五、从源码看join()方法

    在AThread的run方法里,执行了bt.join();,进入看一下它的JDK源码:

    [java]  view plain  copy
    1. public final void join() throws InterruptedException {  
    2.     join(0L);  
    3. }  
    然后进入join(0L)方法:
    [java]  view plain  copy
    1. public final synchronized void join(long l)  
    2.     throws InterruptedException  
    3. {  
    4.     long l1 = System.currentTimeMillis();  
    5.     long l2 = 0L;  
    6.     if(l < 0L)  
    7.         throw new IllegalArgumentException("timeout value is negative");  
    8.     if(l == 0L)  
    9.         for(; isAlive(); wait(0L));  
    10.     else  
    11.         do  
    12.         {  
    13.             if(!isAlive())  
    14.                 break;  
    15.             long l3 = l - l2;  
    16.             if(l3 <= 0L)  
    17.                 break;  
    18.             wait(l3);  
    19.             l2 = System.currentTimeMillis() - l1;  
    20.         } while(true);  
    21. }  

    单纯从代码上看: * 如果线程被生成了,但还未被起动,isAlive()将返回false,调用它的join()方法是没有作用的。将直接继续向下执行。 * 在AThread类中的run方法中,bt.join()是判断bt的active状态,如果bt的isActive()方法返回false,在bt.join(),这一点就不用阻塞了,可以继续向下进行了。从源码里看,wait方法中有参数,也就是不用唤醒谁,只是不再执行wait,向下继续执行而已。 * 在join()方法中,对于isAlive()和wait()方法的作用对象是个比较让人困惑的问题:

    isAlive()方法的签名是:public final native boolean isAlive(),也就是说isAlive()是判断当前线程的状态,也就是bt的状态。

    wait()方法在jdk文档中的解释如下:

    Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).

    The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

    在这里,当前线程指的是at。

HDRP shader 获取阴影(Custom Pass) Unity:2021.3.0f1 HDRP:12.1.6 阅读详情

相关推荐

FPGA实战:用DDR3和乒乓操作解决视频帧撕裂问题(附Verilog代码)

本文详细介绍了如何利用DDR3内存和乒乓操作架构解决FPGA视频处理中的帧撕裂问题。通过多帧缓存原理、AXI接口配置和自适应乒乓操作设计,有效隔离读写操作,确保视频流稳定传输。文章包含Verilog代码实现和性能优化技巧,适用于工业相机、医疗影像等高速视频处理场景。

m2n3b4v5c6的博客 290

Thread 的 join() 方法

关于 Thread 的 join 方法 1、join() 方法说明2、代码演示2.1 添加 join() 方法后2.2 添加 join() 方法前2.3 对比说明3、源码理解   线程模块,计划用一个系列博文整理总结。上一篇博文:  《线程系列1:创建线程》     1、join() 方法说明   join() 是Thread的实例方...

STRANGE-P 的博客 1万+

广义标签多伯努利滤波器(GLMB):多目标跟踪中的动态身份维护理论与算法解析

目标集表示Xx1l1x2l2xNlNX{(x1​l1​x2​l2​xN​lN​)}xi∈Rdxi​∈Rd为目标状态(如位置、速度),li∈Lli​∈L为唯一标签(可数无限集,如自然数序列),N 为目标数(允许N0N=0N0,即空集)。GLMB 通过广义化标签多伯努利分布,将多目标跟踪从 “状态估计” 提升至 “动态身份 - 状态联合建模”,成为复杂场景下精准跟踪的核心技术。

qq_44965657的博客 1601

Thread.join()

Thread.join():join()的作用是“等待该进程终止”,也就是在子线程调用了join()方法后,主线程后面的代码要等到子线程结束了才能执行。一般应用于一个线程的输入可能依赖于另一个或者多个线程的输出,此时这个线程就需要等待依赖线程执行完毕才能继续执行。 public final void join() throws InterruptedException public fina...

m0_37637141的博客 4665

Dataset - DeepFashion 服装数据集

Dataset - DeepFashion 服装数据集 [Dataset - DeepFashion] [Project - DeepFashion] 1. 服装类别和属性预测集 [Category - Attribute 下载] [百度网盘] 289,222 张服装图片 clothes images; 50 个服装类别 clothing categories 1,000 ...

长风破浪会有时,直挂云帆济沧海 2万+

H无穷控制学习笔记——加权灵敏度H无穷控制问题

一、加权灵敏度H无穷问题 系统结构如上图所示。被控对象P的状态空间方程为(Ap,Bp,Cp,DpA_p,B_p,C_p,D_pAp​,Bp​,Cp​,Dp​),加权函数W1的状态空间方程为(A1,B1,C1,D1A_1,B_1,C_1,D_1A1​,B1​,C1​,D1​),加权函数W2的状态空间方程为(A2,B2,C2,D2A_2,B_2,C_2,D_2A2​,B2​,C2​,D2​),加权函数W3的状态空间方程为(A3,B3,C3,D3A_3,B_3,C_3,D_3A3​,B3​,C3​,D3​)。

一饮丶一啄的博客 4350

Thread之三:Thread Join()的用法

一、join用法 join()和wait()不会释放锁,join()是Thread的方法,wait()是Object的方法 1.join方法定义在Thread类中,则调用者必须是一个线程 例如: Thread t = new CustomThread();//这里一般是自定义的线程类 t.start();//线程起动 t.join();//此处会抛出InterruptedExcept...

bingguang1993的博客 9037

玩转Docker | 使用Docker部署MediaCMS内容管理系统

玩转Docker | 使用Docker部署MediaCMS内容管理系统

qq_59334230的博客 2920

Java Thread中的join()方法解释

Join作用 join是定义在Thread类中的方法,作用是阻塞当前线程的执行,等到被调用join的线程对象执行完毕才执行继续执行当前线程。在Java源码中的定义如下: public final void join() throws InterruptedException { join(0); } public final synchronized void join(long millis) throws InterruptedException 接下来我们先来看看join的简单使用,这样能

wenhonglian的博客 8868

HRNet训练自己的分类数据

1.搭建环境 为了防止和服务器上的环境冲突,这里利用conda搭建环境。 Install PyTorch=0.4.1 following theofficial instructions git clonehttps://github.com/HRNet/HRNet-Image-Classification Install dependencies: pip install -r requirements.txt ...

C/C++、嵌入式开发、深度学习算法、模型部署与推理优化 5849

Python遥感图像处理应用篇(二十三):Python+GDAL 批量拼接图像

遥感影像拼接分多种不同的情况,比如比较常用的是两幅影像拼接或者多个图像合并为一个图像。GDAL中实现影像拼接的方式也有多种,比如常用可以通过numpy读取影像数组,并计算各个图像的numpy数组范围,合并多个numpy数组为一个最终的结果,并将其重新输出为一幅新的图像,即可实现图像的拼接。另外比较方便的一种方法便是使用GDAL.warp()函数方法。这个函数的功能很多,可以实现多种不同的目的,比如用于坐标系转换、投影变换、图像合并与镶嵌、地理范围裁剪、更改分辨率、矢量裁剪等多种功能。这些功能可以通过设置Op

soderayer的博客 4643

多线程中Thread的join方法

多线程中Thread的join方法 join简介 join方法是Thread类中的一个方法,该方法的定义是等待该线程执行直到终止。其实就说join方法将挂起调用线程的执行,直到被调用的对象完成它的执行。 join实例(以一道面试题为例) 现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完之后执行,T3在T2执行完后执行?这个问题是网上很热门的面试题(这里除了join还有很多方法能够实现,只是使用join是最简单的方案),下面是实现的代码: /** * @author wcc * @date 20

weixin_46410481的博客 3万+

MicroBlaze系列教程(5):AXI_UART16550的使用

axi-uart16550是Xilinx的一款串口IP核,支持配置成16450或16550模式,16550和16450是指的早期电脑主板上的串口芯片型号,16550相比于16450多了FIFO,现在已经很少使用。相比于,16550支持1或2位停止位,包括uartlite所有的功能,而且支持在SDK中灵活对波特率、数据、校验方式进行配置。与uartlite不同的是,不能单独指定发送中断和接收中断函数,只有一个中断函数,通过event参数来区分当前是发送或接收中断。

whik1194的博客 4544

Thread.join()方法详解

API:   join public final void join() throws InterruptedException 等待该线程终止。   抛出: InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。     join public final v...

1771

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Java Thread.join()详解

原文地址:Java Thread.join()详解 一、使用方式。 join是Thread类的一个方法,启动线程后直接调用,例如: Thread t = new AThread(); t.start(); t.join(); 二、为什么要用join()方法 在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他...

Japathy 840

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

java 线程 thread.join_Java Thread.join() 方法详解

有些知识点还是要一个一个来,一文秒懂 系列还是来的有点肤浅。这几天开始尝试深入 API 层写一些东西,看看效果如何?本章节我尝试详细的介绍下 Thread.join() 方法。然后过几天回来看看这篇文章的质量如何?Thread.join() 方法有许多重载,可用于各种场景,本文也会针对一些较常见的场景写一些使用 Thread.join() 的示例。Thread.join() 方法Thread.jo...

weixin_42297562的博客 577

Java 中的 Thread.join() 方法详解

在多线程编程中,线程的管理和协调是一个重要课题。Java 提供了多种机制来实现线程之间的协调,其中之一就是方法。join()方法允许一个线程等待另一个线程完成,这在很多场景中是非常有用的。例如,当我们需要确保某个任务在继续之前必须先完成另一个任务时,join()方法就是一个很好的选择。

csdn_life18的博客 2844

c# Thread.Join()详解

Thread.Join()在MSDN中的解释很模糊:Blocks the calling thread until a thread terminates 有两个主要问题:1.什么是the calling thread? 2.什么是a thread? 首先来看一下有关的概念: 我们执行一个.exe文件实际上就是开启了一个进程,...

weixin_33772645的博客 111

php thread join,Python Thread join()用法详解

前面章节中,我们讲解了如何通过 Thread 类创建并启动一个线程,当时给读者用如下的程序进行演示:import threading #定义线程要调用的方法,*add可接收多个以非关键字方式传入的参数 def action(*add): for arc in add: #调用 getName() 方法获取当前执行该程序的线程名 print(thre...

weixin_33260484的博客 169
上一篇: Android studio 检测代码是否规范的工具
下一篇: Android硬编码——音频编码、视频编码及音视频混合
闲暇部落
博客等级 码龄12年 2777粉丝 215原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲暇部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值