JAVA多线程之方法 JOIN详解及实例代码

发布时间 - 2026-01-10 23:03:28    点击率:

JAVA多线程 JOIN

 对于Java开发人员,多线程应该是必须熟练应用的知识点,特别是开发基于Java语言的产品。本文将深入浅出的表述Java多线程的知识点,在后续的系列里将侧重于Java5由Doug Lea教授提供的Concurrent并行包的设计思想以及具体实现与应用。

    如何才能深入浅出呢,我的理解是带着问题,而不是泛泛的看。所以该系列基本以解决问题为主,当然我也非常希望读者能够提出更好的解决问题的方案以及提出更多的问题。由于水平有限,如果有什么错误之处,请大家提出,共同讨论,总之,我希望通过该系列我们能够深入理解Java多线程来解决我们实际开发的问题。

    作为开发人员,我想没有必要讨论多线程的基础知识,比如什么是线程? 如何创建等 ,这些知识点是可以通过书本和Google获得的。本系列主要是如何理深入解多线程来帮助我们平时的开发,比如线程池如何实现? 如何应用锁等。 

(1)方法Join是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答。
    自从接触Java多线程,一直对Join理解不了。JDK是这样说的:

  join
  public final void join(long millis)throws InterruptedException
  Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.

 大家能理解吗? 字面意思是等待一段时间直到这个线程死亡,我的疑问是那个线程,是它本身的线程还是调用它的线程的,上代码:

package concurrentstudy;
/**
 *
 * @author vma
 */
public class JoinTest {
  public static void main(String[] args) {
    Thread t = new Thread(new RunnableImpl());
    t.start();
    try {
      t.join(1000);
      System.out.println("joinFinish");
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   
    }
  }
}
class RunnableImpl implements Runnable {

  @Override
  public void run() {
    try {
      System.out.println("Begin sleep");
      Thread.sleep(1000);
      System.out.println("End sleep");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }
}

结果是:

Begin sleep
End sleep
joinFinish

明白了吧,当main线程调用t.join时,main线程等待t线程,等待时间是1000,如果t线程Sleep 2000呢 

 public void run() {
    try {
      System.out.println("Begin sleep");
      // Thread.sleep(1000);
      Thread.sleep(2000);
      System.out.println("End sleep");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

结果是:

Begin sleep
joinFinish
End sleep

也就是说main线程只等1000毫秒,不管T什么时候结束,如果是t.join()呢, 看代码:  

public final void join() throws InterruptedException {
  join(0);
  }

就是说如果是t.join() = t.join(0) 0 JDK这样说的 A timeout of 0 means to wait forever 字面意思是永远等待,是这样吗?
其实是等到t结束后。

这个是怎么实现的吗? 看JDK代码:

 /**
   * Waits at most <code>millis</code> milliseconds for this thread to 
   * die. A timeout of <code>0</code> means to wait forever. 
   *
   * @param   millis  the time to wait in milliseconds.
   * @exception InterruptedException if any thread has interrupted
   *       the current thread. The <i>interrupted status</i> of the
   *       current thread is cleared when this exception is thrown.
   */
  public final synchronized void join(long millis) 
  throws InterruptedException {
  long base = System.currentTimeMillis();
  long now = 0;

  if (millis < 0) {
      throw new IllegalArgumentException("timeout value is negative");
  }

  if (millis == 0) {
    while (isAlive()) {
    wait(0);
    }
  } else {
    while (isAlive()) {
    long delay = millis - now;
    if (delay <= 0) {
      break;
    }
    wait(delay);
    now = System.currentTimeMillis() - base;
    }
  }
  }

其实Join方法实现是通过wait(小提示:Object 提供的方法)。 当main线程调用t.join时候,main线程会获得线程对象t的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程,比如退出后。

这就意味着main 线程调用t.join时,必须能够拿到线程t对象的锁,如果拿不到它是无法wait的,刚开的例子t.join(1000)不是说明了main线程等待1秒,如果在它等待之前,其他线程获取了t对象的锁,它等待时间可不就是1毫秒了。上代码介绍:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package concurrentstudy;
/**
 *
 * @author vma
 */
public class JoinTest {
  public static void main(String[] args) {
    Thread t = new Thread(new RunnableImpl());
    new ThreadTest(t).start();
    t.start();
    try {
      t.join();
      System.out.println("joinFinish");
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   
    }
  }
}
class ThreadTest extends Thread {

  Thread thread;

  public ThreadTest(Thread thread) {
    this.thread = thread;
  }

  @Override
  public void run() {
    holdThreadLock();
  }

  public void holdThreadLock() {
    synchronized (thread) {
      System.out.println("getObjectLock");
      try {
        Thread.sleep(9000);

      } catch (InterruptedException ex) {
       ex.printStackTrace();
      }
      System.out.println("ReleaseObjectLock");
    }

  }
}

class RunnableImpl implements Runnable {

  @Override
  public void run() {
    try {
      System.out.println("Begin sleep");
      Thread.sleep(2000);
      System.out.println("End sleep");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }


  }
}

在main方法中 通过new ThreadTest(t).start();实例化ThreadTest 线程对象, 它在holdThreadLock()方法中,通过synchronized (thread),获取线程对象t的锁,并Sleep(9000)后释放,这就意味着,即使main方法t.join(1000),等待一秒钟,它必须等待ThreadTest 线程释放t锁后才能进入wait方法中,它实际等待时间是9000+1000 MS

运行结果是:

getObjectLock
Begin sleep
End sleep
ReleaseObjectLock
joinFinish

小结:

本节主要深入浅出join及JDK中的实现。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# JAVA多线程之方法  # JOIN详解  # java  # JOIN  # java基本教程之join方法详解 java多线程教程  # java 中Thread.join()的使用方法  # Java之Thread的join方法实例  # java线程之join方法的使用介绍  # java多线程编程之join方法的使用示例  # Java多线程中关于join方法的使用实例解析  # Java使用join方法暂停当前线程  # Java字符串拼接新方法 StringJoiner用法详解  # 浅谈Java线程Thread.join方法解析  # java中join方法的理解与说明详解  # 多线程  # 深入浅出  # 是这样  # 这就  # 解决问题  # 结果是  # 开发人员  # 到该  # 有什么  # 我也  # 我想  # 带着  # 什么时候  # 之处  # 是怎么  # 请大家  # 它是  # 可以通过  # 希望能  # 可不 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: PHP 500报错的快速解决方法  如何快速查询网址的建站时间与历史轨迹?  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  深圳网站制作的公司有哪些,dido官方网站?  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  如何续费美橙建站之星域名及服务?  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  如何快速上传自定义模板至建站之星?  如何在IIS中新建站点并解决端口绑定冲突?  php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】  油猴 教程,油猴搜脚本为什么会网页无法显示?  jQuery 常见小例汇总  利用python获取某年中每个月的第一天和最后一天  Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南  如何在云服务器上快速搭建个人网站?  java中使用zxing批量生成二维码立牌  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  如何在 React 中条件性地遍历数组并渲染元素  简单实现jsp分页  简单实现Android验证码  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作  JS去除重复并统计数量的实现方法  nginx修改上传文件大小限制的方法  长沙做网站要多少钱,长沙国安网络怎么样?  jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】  HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】  香港服务器网站卡顿?如何解决网络延迟与负载问题?  如何在Windows 2008云服务器安全搭建网站?  如何用已有域名快速搭建网站?  Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】  googleplay官方入口在哪里_Google Play官方商店快速入口指南  如何在IIS7中新建站点?详细步骤解析  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  如何快速搭建个人网站并优化SEO?  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  非常酷的网站设计制作软件,酷培ai教育官方网站?  Android Socket接口实现即时通讯实例代码  如何确保西部建站助手FTP传输的安全性?  邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?  如何快速使用云服务器搭建个人网站?  Swift中switch语句区间和元组模式匹配  Laravel如何实现用户密码重置功能?(完整流程代码)  如何用免费手机建站系统零基础打造专业网站?