Thread.join()简单介绍

Android2024年7月31日 pm6:38发布2个月前更新 91es.com站长
64 0 0
目录

前言

简单记录一下Thread.join()的作用。

这里只是简单记录一下,方便自己回顾而已。

正文

join()是在Thread.java中定义

join源码

/**
 * Waits for this thread to die.[等待这个线程死亡]
 * @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);
}

最终调用的是 join(long millis)

public final void join(long millis)
throws InterruptedException {
    synchronized(lock) {
    long base = System.currentTimeMillis();
    long now = 0;
    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }
    //如果传入0,就走这
    if (millis == 0) {
        //判断是否存活
        while (isAlive()) {
            //0时表示一直等待,直到notifyAll()或notify()通知
            lock.wait(0);
        }
    } else {
        while (isAlive()) {
            //倒计时
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            //等待指定的时间
            lock.wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
    }
}
  1. 如果传入值millis为0时,需要等待线程死亡(任务结束)才会释放。

  2. 如果传入值millis大于0时,要么倒计时结束主动释放,要么线程死亡(任务结束),满足其一即可退出。

demo测试

下面简单的测试一下。先定义一个线程,如下。

private class MyThread extends Thread {
    public MyThread(String name) {
        setName(name);
    }

    @Override
    public void run() {
        super.run();
        Log.d(TAG, "name : " + getName() + " start ");
        for (int i = 0; i < 5; i++) {
            try {
                Log.d(TAG, "name : " + getName() + " [ " + i + " ] ");
                sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        Log.d(TAG, "name : " + getName() + " end ");
    }
}
不使用join()
private void test() {
    MyThread myThreadA = new MyThread("Thread_A");
    myThreadA.start();
    Log.d(TAG, "name : " + Thread.currentThread().getName() + " start ");
    for (int i = 0; i < 5; i++) {
        Log.d(TAG, "name : " + Thread.currentThread().getName() + " [ " + i + " ] ");
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    Log.d(TAG, "name : " + Thread.currentThread().getName() + " end ");
}

在main()中执行test()方法。执行后打印结果如下:

name : main start 
name : Thread_A start 
name : main [ 0 ] 
name : Thread_A [ 0 ] 
name : main [ 1 ] 
name : Thread_A [ 1 ] 
name : main [ 2 ] 
name : Thread_A [ 2 ] 
name : main [ 3 ] 
name : Thread_A [ 3 ] 
name : main [ 4 ] 
name : Thread_A [ 4 ] 
name : main end 
name : Thread_A end 

main线程和Thread_A一起抢占CPU资源的。

使用join()

下面代码是在上面基础上添加了join()方法,如下:

private void test() {
    MyThread myThreadA = new MyThread("Thread_A");
    myThreadA.start();
    //添加join()开始
    try {
        myThreadA.join();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    //添加join()结束
    Log.d(TAG, "name : " + Thread.currentThread().getName() + " start ");
    for (int i = 0; i < 5; i++) {
        Log.d(TAG, "name : " + Thread.currentThread().getName() + " [ " + i + " ] ");
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    Log.d(TAG, "name : " + Thread.currentThread().getName() + " end ");
}

在main()中执行test()方法。执行后打印结果如下:

name : Thread_A start 
name : Thread_A [ 0 ] 
name : Thread_A [ 1 ] 
name : Thread_A [ 2 ] 
name : Thread_A [ 3 ] 
name : Thread_A [ 4 ] 
name : Thread_A end 
name : main start 
name : main [ 0 ] 
name : main [ 1 ] 
name : main [ 2 ] 
name : main [ 3 ] 
name : main [ 4 ] 
name : main end 

上面的打印顺序是有顺序了,都规规矩矩的。也就是CPU一直被Thread_A占用,main老老实实等着Thread_A死亡才可以抢CPU。

小结

  1. 调用join()的线程具有优先执行权。

  2. 当有线程调用join()后,其他线程会阻塞,直到调用join()线程死亡。

参考文章

  1. 《Java并发编程之美》

  2. 《Thread.java源码》

 历史上的今天

  1. 2023: init的启动(0条评论)
  2. 2022: [摘]Android输入法基于GooglePinyin开源代码进行修改(0条评论)
  3. 2021: 梁小斌:中国,我的钥匙丢了(0条评论)
  4. 2019: 叔本华:只有经过深思的东西才能成为真知(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com[备用域名]
3、 本站内容: 部分来源于网络,仅供站长学习和参考,若侵权请留言

暂无评论

暂无评论...

随机推荐

媒体封面流RecyclerCoverFlow左右滚动

前言本文没有创新,使用其他大佬代码进行定制化的,参考文章请看文末。主要是删减了部分功能和增加了无限循环等。记录于此,方便自己翻阅。正文效果如图隐藏内容!付费阅读后才能查看!¥6多个隐藏块只需支付一次付费阅读参考文章《GitHub - ChenLittlePing/Recycler...

米兰.昆德拉:二十四只鹧鸪

过完漫长辛苦的白天,斯大林喜欢跟他的合作者再呆上一会儿,休息中给他们说说自己生活中的小故事。比如说下面这个:一天,他决定去打猎。他穿上一件老派克,系好滑雪板,拿起一支长猎枪,跑了十三公里。那时候,他看到前面一棵树上停着几只鹧鸪。他停步,数了数,二十四只。但是运气不好!他身上只带了十二发子弹!他开枪...

无效的UTF-8字符串引发的问题

前言最近在调试多媒体时,出现特别奇怪的问题,也就是扫描磁盘中文件时被中断了,之前都是好的。记录于此,方便自己查阅。好记性不如烂笔头正文部分异常日志如下。 signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort...

WordPress部分内容输入密码可见

1、将以下代码添加到Three主题的functions.php文件最后一个?>的前面。/* Name: 部分内容输入密码可见(短代码) * 作者:E享乐(www.exiang2.com) */function e_secret($atts, $content=null){ ex...

adb命令打印cpu信息

有时候系统出现问题可能和当前的 CPU 等资源紧张有关系。那么如何实时打印系统当前的 CPU 占用的情况呢?输入命令:adb shell top -m 5该命令会打印当前使用 CPU 前5位的进程相关的信息,每隔1s更新一次User 6%, System 3%, IOW 0%, ...

[摘]车载MediaSession框架理解

前言本文内容主要介绍Android车载多媒体开发MediaSession框架知识,而且内容是阅读参考文的笔记。记录于此,方便自己查阅。好记性不如烂笔头。正文这里摘抄我自己想了解的,而且只是记录一下,有兴趣的还是看原文,多谢理解。Android AutoAndroid Auto就是...