当前位置: 首页 > 知识库问答 >
问题:

如果join阻塞主线程,为什么它不阻塞循环?

窦夜洛
2023-03-14

线程实例的join()方法可用于将一个线程的执行开始“连接”到另一个线程的执行结束,这样一个线程在另一个线程结束之前不会开始运行。如果对线程实例调用join(),则当前运行的线程将阻塞,直到线程实例完成执行

但是如果我有多个线程并且当我在循环内部调用join时。所有线程并行运行。但是根据连接的概念,首先连接的线程应该完成,然后只有主线程才允许连接其他线程。

public class MultiThreading implements Runnable {


private int name;
public MultiThreading(int number) {
    name =number;
}

@Override
public void run() {
    for (int i = 0; i <= 10; i++ ) {

           System.out.println("Thread number :" + name +" Printed value "+i);

        try {
            Thread.sleep(100);
        } catch (final InterruptedException e) {
            return;
        }
    }
}


public static void main(String[] args) throws InterruptedException {

    final Thread[] workers = new Thread[3];
    for (int i = 0; i < nthreads; ++i) {
        workers[i] = new Thread(new MultiThreading(i));
    }
    for (final Thread t : workers) {
        t.start();

    }

    for (final Thread t : workers) {
        t.join();
        System.out.println("Thread joind to main thread : " + t.getName());
    }
    System.out.println("Main thread ends");
}

}

在上面的代码中,如果第一个线程被连接,那么主线程应该被阻塞,并且它不应该让其他线程连接(直到被连接的线程完成run方法的执行)。但所有线程都是并行连接的。输出就像-

Thread number :0 Printed value 0
Thread number :1 Printed value 0
Thread number :2 Printed value 0
Thread number :0 Printed value 1
Thread number :1 Printed value 1
Thread number :2 Printed value 1
Thread number :0 Printed value 2
Thread number :1 Printed value 2
Thread number :2 Printed value 2
Thread number :0 Printed value 3
Thread number :1 Printed value 3
Thread number :2 Printed value 3
Thread number :0 Printed value 4
Thread number :1 Printed value 4
Thread number :2 Printed value 4
Thread number :1 Printed value 5
Thread number :0 Printed value 5
Thread number :2 Printed value 5
Thread number :0 Printed value 6
Thread number :1 Printed value 6
Thread number :2 Printed value 6
Thread number :1 Printed value 7
Thread number :0 Printed value 7
Thread number :2 Printed value 7
Thread number :0 Printed value 8
Thread number :1 Printed value 8
Thread number :2 Printed value 8
Thread number :1 Printed value 9
Thread number :0 Printed value 9
Thread number :2 Printed value 9
Thread number :1 Printed value 10
Thread number :0 Printed value 10
Thread number :2 Printed value 10
Thread joind to main thread : Thread-0
Thread joind to main thread : Thread-1
Thread joind to main thread : Thread-2
Main thread ends

共有1个答案

李洋
2023-03-14

首先:

线程实例的join()方法可用于将一个线程的执行开始“连接”到另一个线程的执行结束

这是一个误解:这与启动线程无关。Join只做这个:一个正在运行的线程会一直等到另一个线程结束。

当您执行someThread.join()时,调用该方法的线程将等待,直到someThread结束!

但所有线程都是并行连接的。

是的,因为他们都完成了。

您的线程所做的一切都是完全相同的,因此除了几纳秒(由于写入System.out可以有效地同步数据,所以这些数据大多是无效的)之外,它们都需要相同的时间。

所以当你加入第一个线程的时候...其他两个线程就完成了。因此,对join()的第一个调用使“main”线程等待第一个线程结束,随后的调用“立即”发生,因为这些线程也已完成。

为了延迟时间,请将循环数作为multithreading类的一个参数,然后确保线程需要不同的时间。如果线程-0执行10个循环,线程-1执行20个循环,而线程-2执行30个循环,您将看到每个连接实际上都在等待相应的线程结束。

长话短说:您立即启动所有线程,因此它们立即开始并行运行。稍后的join调用只是延迟主线程的进程,直到每个工作线程结束。

 类似资料:
  • 我不明白为什么webclient会阻止我使用gradle的主要netty线程,以下是它的依赖项: 这个gradle脚本在两个应用程序中都使用。在第一个应用程序中,我执行: 第二个应用程序模拟长响应处理: 我希望呼叫服务不会阻塞主线程,而是会继续处理传入的连接,但直到我收到第一个呼叫的响应(睡眠将起作用),我的下一个连接将挂起等待。 结果:第一个应用程序像tomcat一样工作,只有一个线程 我的问题

  • 问题内容: 当用户选择在另一个线程中启动阻止进程的菜单项时,我试图在JavaFX 8应用程序中提供反馈。在我的实际应用程序中,它是文件下载,但是通过示例,我使用最少的代码创建了一个测试用例: 它的工作方式如下:当选择“开始”菜单项时,主菜单文本应立即更改为“正在运行…”,然后应附加“完成!”。经过5秒钟的模拟我的文件下载的睡眠。 实际上发生的是,即使我正在使用,在阻止过程完成 后 , 两个 文本更

  • 我不明白以下几点: 用户级线程需要非阻塞系统调用,即多线程内核。否则,整个进程将在内核中阻塞,即使进程中还有可运行的线程。 内核线程如何处理阻塞系统调用?在用户级线程中,当一个线程进行阻塞系统调用(例如读取)时,为什么其他线程不能继续工作?

  • 问题内容: 更新: 这看起来像是内存问题。一个3.8 Gb Hprof文件表明,发生此“阻塞”时,JVM正在对其堆进行转储。我们的运营团队发现该站点没有响应,进行了堆栈跟踪,然后关闭了实例。我相信他们在堆转储完成之前就关闭了该站点。日志中 没有 错误/异常/问题证据-可能是因为JVM在生成错误消息之前就被杀死了。 最初的问题我们最近遇到了一种情况,该应用程序对最终用户似乎挂起了。在应用程序重新启动

  • 问题内容: 注意:这不是有关settimeout的复制文章,此处的关键答案是浏览器设计选项。 我开始研究node.js:一个测试异步的简单示例: 一件有趣的事情是,在带有curl的lind命令和浏览器中,它的行为是不同的:在Ubuntu 12.10中,我在两个控制台中使用curl localhost:8080,它们在几乎相同的10个发送中进行响应。 但是,我打开了两个浏览器,几乎同时发出了请求,但

  • 我有下面的代码片段,它试图在多个子进程之间分割处理。 while循环中的主进程正在调用search函数,如果队列达到阈值计数,则处理池将映射到进程函数,其中作业来自队列。我的问题是,python多处理池是在执行期间阻塞主进程,还是立即继续执行?我不想遇到这样的情况,“has_jobs_to_process()”的计算结果为true,并且在处理作业的过程中,另一组作业的计算结果为true,并且再次调