多线程之join方法

多线程之join方法一.前言:    在很多情况下,我们都是通过主线程创建并启动子线程的,如果子线程中需要耗费大量的时间计算的话,主线程往往会比子线程先结束,这个时候就会导致有时候主线程想获取子线程计算之后的结果,但是却获取不到。这个时候,我们就可以通过join方法来解决这个问题。二.join方法的作用:join方法的作用是使所属的线程对象x正常执行run()方法中的任务,而使当前线程z进行无限期的…

大家好,又见面了,我是你们的朋友全栈君。

一.前言:

       在很多情况下,我们都是通过主线程创建并启动子线程的,如果子线程中需要耗费大量的时间计算的话,主线程往往会比子线程先结束,这个时候就会导致有时候主线程想获取子线程计算之后的结果,但是却获取不到。这个时候,我们就可以通过join方法来解决这个问题。

二.join方法的作用:

join方法的作用是使所属的线程对象x正常执行run()方法中的任务,而使当前线程z进行无限期的阻塞,等待线程x销毁后再继续执行线程z后面的代码。方法join具有使线程排队运行的作用,有些类似同步的运行效果。

下面看一个例子:

public class MyThread extends Thread{
    @Override
    public void run() {
        int sencondValue = (int)(Math.random()*1000);
        System.out.println(sencondValue);
        try {
            Thread.sleep(sencondValue);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class Run {
    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        myThread.join();
        System.out.println("当对象myThread执行完毕后再执行");
    }
}

运行结果:多线程之join方法join的意思是使得放弃当前线程的执行,并返回对应的线程,例如上面代码的意思就是:程序在main线程中调用myThread线程的join方法,则main线程放弃cpu控制权,并返回myThread线程继续执行直到线程myThread执行完毕。所以结果是线程myThread执行完后,才到主线程执行,相当于在main线程中同步线程myThreadmyThread执行完了,main线程才有执行的机会 此外,join方法和interrupt方法相遇的时候会抛出异常。

此外,还有join(long millis)方法,指定要等待多长时间。

三.join的实现原理:

查看join方法源码:

/**
     * Waits for this thread to die.
     *
     * <p> An invocation of this method behaves in exactly the same
     * way as the invocation
     *
     * <blockquote>
     * {@linkplain #join(long) join}{@code (0)}
     * </blockquote>
     *
     * @throws  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 void join() throws InterruptedException {
        join(0);
    }
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方法, 来实现同步的效果的。例如,A线程中调用了B线程的join方法,则相当于A线程调用了B线程的wait方法,在调用了B线程的wait方法后,A线程就会进入阻塞状态,因为它相当于放弃了CPU的使用权。需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()。

四.join方法和synchronized、sleep方法的区别:

1.从上面的源码我们可以看出,join(long millis)是通过在内部使用wait(long millis)方法来实现的,所有它其实是具有释放锁的特点的,在执行完;而sleep(long millis)是不释放锁的,也就是如果有Synchronized同步块,其他线程仍然不能访问共享数据。注意该方法要捕获异常。

2.join在内部使用wait()方法进行等待,而synchronized关键字使用的是“对象监控器”原理做同步,具体可以看这个synchronized原理

 

参考:https://www.2cto.com/kf/201608/543154.html

           https://www.cnblogs.com/lcplcpjava/p/6896904.html

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/136897.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 分子动力学模拟软件_材料领域十大常用绘图软件

    作为材料领域的科研工作者,你是否常为如何表达自己的思想而苦恼?作为学术论文创造者,你是否为论文中图文单一而叹气?在这里,GO小妹推荐给你几款常用绘图软件,让你论文从此成为焦点!1——OriginProOringinPro的主要功能为数据分析和绘图。Origin的数据分析主要包括统计、信号处理、图像处理、峰值分析和曲线拟合等各种完善的数学分析功能。进行数据分析时,只需将原始数据粘贴进Origin表格…

    2022年4月3日
    844
  • idea替换所有文件中的内容[通俗易懂]

    idea替换所有文件中的内容[通俗易懂]通过快捷键Ctrl+Shift+R打开窗口,或者通过点击Edit–>Find–>Replaceinpath打开窗口。输入被替换和要替换的内容后,点击replaceall即可替换全部。

    2022年9月29日
    6
  • pycharm中pip install如何使用_pycharm使用pip安装第三方库

    pycharm中pip install如何使用_pycharm使用pip安装第三方库pyCharm如何使用通过CMDpipinstall方式安装的依赖包前言将pyCharm的解释器设置成Python解释器的方法前言在window下通过cmd(win+r打开运行,然后输入cmd,按下回车即可打开)方式来安装Python依赖包是一种方便快捷的方式。但是往往很多时候由于pyCharm与Python安装在不同的路径,即使你已经用cmdpipinstall的方式在你的电…

    2022年8月26日
    18
  • 51单片机学习笔记:合并1602和12864液晶排插接口

    51单片机学习笔记:合并1602和12864液晶排插接口 今天成功合并1602和12864液晶排插接口! 码出来分享下 上面这2个图是1602和12864液晶的排插接口,一般的单片机开发板上都会有仔细观察发现他们的插口大多是相同的, 对于第三脚的对比度调节,1602和12864液晶在硬件上是相反的(1602是低电位方向对比度增强,12864是高电位方向对比度增强),但他们接口位置相同,所以一个10K左右的3脚电位器…

    2022年10月20日
    2
  • redis源码 -ziplist

    注释的翻译:/*Theziplistisaspeciallyencodedduallylinkedlistthatisdesigned*tobeverymemoryefficient.Itstoresbothstringsandintegervalues,*whereintegersareencodedasactualint

    2022年4月10日
    38
  • struts2核心控制器在哪里配置_intercontrol控制器

    struts2核心控制器在哪里配置_intercontrol控制器原文:http://mopishv0.blog.163.com/blog/static/54455932200981295843192/1.   在struts1.x系列中,所有的请求是通过一个servlet(ActionServlet)来管理控制的,在Struts2.X而是经过一个Filter来处理请求的。Struts2将核心控制器设计成Filter,而不是一个普通Servlet。struts1.x中actionorg.apache.struts.action.ActionServlet。。。St

    2022年8月16日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号