当前位置: 首页 > article >正文

java线程中,join()方法?

java线程中的,join()方法:

java线程的 join() 方法的简单总结

一、join()方法的作用:

Thread线程类对象 调用的 join() 方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行。
具体看代码:

  1. join() 方法不带参数
public class JoinTest {

    public static void main(String [] args) throws InterruptedException {
        ThreadJoinTest t1 = new ThreadJoinTest("小明");
        ThreadJoinTest t2 = new ThreadJoinTest("小东");
        t1.start();
        /**join的意思是使得放弃当前线程的执行,并返回对应的线程,例如下面代码的意思就是:
         程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到线程t1执行完毕
         所以结果是t1线程执行完后,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会
         */
        t1.join();   //   t1.join(0)  等价于   t1.join()
        t2.start();
    }

}

class ThreadJoinTest extends Thread{   //定义一个线程类

    public ThreadJoinTest(String name){
        super(name);
    }
    
    @Override
    public void run(){
        for(int i=0;i<1000;i++){
            System.out.println(this.getName() + ":" + i);
        }
    }
    
}

上面程序结果是先打印完t1小明线程,在打印t2小东线程;

上面注释也大概说明了join方法的作用:在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行 注意,这里调用的join方法是没有传参的,join方法其实也可以传递一个参数给它的,具体看下面的简单例子:

  1. join(x) 方法带参数
public class JoinTest {

    public static void main(String [] args) throws InterruptedException {
        ThreadJoinTest t1 = new ThreadJoinTest("小明");
        ThreadJoinTest t2 = new ThreadJoinTest("小东");
        t1.start();
        /**join方法可以传递参数,join(10)表示main线程会等待t1线程10毫秒,10毫秒过去后,
         * main线程和t1线程之间执行顺序由串行执行变为普通的并行执行
         */
        t1.join(10);
        t2.start();
    }

}

class ThreadJoinTest extends Thread{
    public ThreadJoinTest(String name){
        super(name);
    }
    
    @Override
    public void run(){
        for(int i=0;i<1000;i++){
            System.out.println(this.getName() + ":" + i);
        }
    }
    
}

上面代码结果是:程序执行前面10毫秒内打印的都是t1小明线程,10毫秒后,小明和小东程序并行打印。

所以,join()方法中如果传入参数,则表示这样的意思: 如果在A线程中调用B线程的join(10)方法,则表示A线程会等待B线程执行10毫秒,10毫秒过后,A、B线程并行执行。
【需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()。】

二、join() 与 start() 先后调用顺序问题:

上面的讨论大概知道了join的作用了,那么,如果 join() 在start() 前调用,会出现什么后果呢?
答案是:不能起到同步作用。

public class JoinTest {

    public static void main(String [] args) throws InterruptedException {
        ThreadJoinTest t1 = new ThreadJoinTest("小明");
        ThreadJoinTest t2 = new ThreadJoinTest("小东");
        /**join方法可以在start方法前调用时,但是并不能起到同步的作用
         */
        t1.join();
        t1.start();
        //Thread.yield();
        t2.start();
    }

}

class ThreadJoinTest extends Thread{
    public ThreadJoinTest(String name){
        super(name);
    }
    @Override
    
    public void run(){
        for(int i=0;i<1000;i++){
            System.out.println(this.getName() + ":" + i);
        }
    }
    
}

上面代码执行结果是:t1线程小明和t2线程小东线程 并行打印。

所以得到以下结论:join()方法必须在线程start()方法调用之后调用才有意义。这个也很容易理解:如果一个线程都没有start,那它也就无法同步了。

三、join() 方法实现原理?

有了上面的例子,我们大概知道join()方法的作用了,那么,join()方法实现的原理是什么呢?

其实,join() 方法是通过调用线程的 wait() 方法来达到同步的目的的。 例如,在A线程中调用了B线程的join() 方法,则相当于A线程调用了B线程的wait()方法,在调用了B线程的wait方法后,A线程就会进入阻塞状态,具体看下面的源码:

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;
            }
        }
        
}

http://www.kler.cn/a/145379.html

相关文章:

  • 【性能优化专题系列】利用CompletableFuture优化多接口调用场景下的性能
  • 基于SpringBoot的假期周边游平台的设计与实现(源码+SQL脚本+LW+部署讲解等)
  • 步进电机加减速公式推导
  • Kmesh v1.0 正式发布
  • docker安装emqx
  • Autogen_core 测试代码:test_cache_store.py
  • Vue 或者 React 中,什么情况下会用 Es6 的 Class类
  • 02 RANSAC算法 及 Python 实现
  • 电商项目高级篇-03 商品上架
  • Elasticsearch集群部署,配置head监控插件
  • 【spring(五)】SpringMvc总结 SSM整合流程
  • GitHub上8个强烈推荐的 Python 项目
  • Vue-报错No “exports“ main defined in xx
  • Leetcode.1590 使数组和能被 P 整除
  • Spring面向切面编程(AOP);Spring控制反转(IOC);解释一下Spring AOP里面的几个名词;Spring 的 IoC支持哪些功能
  • Java中wait()方法在synchronized方法中调用的奥秘
  • php订单发起退款(余额和微信支付)
  • STL: 容器适配器stack 与 queue
  • 什么是proxy代理?
  • NX二次开发UF_CURVE_ask_joined_parms 函数介绍
  • 存算一体还是存算分离?谈谈数据库基础设施的架构选择
  • DDD(领域驱动设计)一些基础概念
  • 【MySQL】JDBC编程
  • 【JVM系列】- 穿插·对象的实例化与直接内存
  • spring boot整合Jasypt实现配置加密
  • tidyverse数据特征学习