2025年3月18日 星期二 甲辰(龙)年 月十七 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 安卓(android)开发

Thread的join函数

时间:02-05来源:作者:点击数:37

在一个开源项目中,有一个录音功能,录音是在一个子线程中完成的,当调用停止录音时,执行的函数如下:

  • public void stopRecordThread() {
  • if (recordThread != null) {
  • try {
  • recordThread.join();
  • } catch (InterruptedException e) {
  • e.printStackTrace();
  • }
  • recordThread = null;
  • }
  • }

查看了JDK文档,join()函数的功能是:等待该线程终止。如上代码,我们调用录音线程的join函数,则是等待录音线程终止,也就是说,如果录音线程没执行完,stopRecord()函数就一直等在那里,是一个阻塞状态,写个示例代码演示如下:

  • public class Main {
  • public static void main(String[] args) {
  • Thread thread = new Thread(Main::printInfo, "Thread");
  • thread.start();
  • printInfo();
  • }
  • public static void printInfo() {
  • try {
  • String name = Thread.currentThread().getName();
  • for (int i = 1; i <= 5; i++) {
  • System.out.println(name + " " + i);
  • Thread.sleep(1000);
  • }
  • } catch (InterruptedException e) {
  • e.printStackTrace();
  • }
  • }
  • }

这里有两个线程都调用了printInfo函数,一个是子线程,一个是主线程,printInfo函数的功能是打印5条信息,每条信息打印了线程名称和序号,每打印一条信息后就睡眠1秒钟,执行效果如下:

  • main 1
  • Thread 1
  • Thread 2
  • main 2
  • Thread 3
  • main 3
  • main 4
  • Thread 4
  • main 5
  • Thread 5

可以看到两个线程同时进行,如果我们希望子线程执行结束之后,再来执行主线程,只需要调用子线程的join函数即可实现,代码如下:

  • public static void main(String[] args) throws InterruptedException {
  • Thread threadA = new Thread(Main::printInfo, "Thread");
  • threadA.start();
  • threadA.join();
  • printInfo();
  • }

执行效果如下:

  • Thread 1
  • Thread 2
  • Thread 3
  • Thread 4
  • Thread 5
  • main 1
  • main 2
  • main 3
  • main 4
  • main 5

可以看到,调用了join()函数后,主线程就被阻塞了,不再往下执行,直到子线程执行结束后再往下执行。

回到文章的开头,一个录音线程,在调用录音Api的停止函数后,系统就不再给出录音数据了,但是录音线程可能还在写录音数据呢,所以要等录音线程执行完毕,不能直接中止录音线程,所以调用了join函数来实现。

后续:子线程执行完之后,子线程自己不就结束了吗?为什么需要调用一个join去把自己阻塞了呢?而且我们看到它调用join()的后面也没写别的代码。我猜啊,这个stopRecordThread()函数是一个回调函数,在别处调用这个函数,则在别处自然就会阻塞住了,所以阻塞之后做了什么就要看是什么地方调用了这个函数。我在这个函数上打印了一下线程名称,发现调用stopRecordThread()函数的函数也是在子线程上运行的,所以虽然阻塞了,但阻塞的是一个子线程,所以不用担心主线程。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门