Java多线程中join方法的理解

简介: 许多同学刚开始学Java 多线程时可能不会关主Join 这个动作,因为不知道它是用来做什么的,而当需要用到类似的场景时却有可能会说Java 没有提供这种功能。

许多同学刚开始学Java 多线程时可能不会关主Join 这个动作,因为不知道它是用来做什么的,而当需要用到类似的场景时却有可能会说Java 没有提供这种功能。

当我们将一个大任务划分为多个小任务,多个小任务由多个线程去完成时,显然它们完成的先后顺序不可能完全一致。在程序中希望各个线程执行完成后,将它们的计算结果最终合并在一起,换句话说,要等待多个线程将子任务执行完成后,才能进行合并结果的操作。
这时就可以选择使用Join 了,Join 可以帮助我们轻松地搞定这个问题,否则就需要用个循环去不断判定每个线程的状态。

在实际生活中,就像把任务分解给多个人去完成其中的各个板块,但老板需要等待这些人全部都完成后才认为这个阶段的任务结束了,也许每个人的板块内部和别人还有相互的接口依赖,如果对方接口没有写好,自己的这部分也不算完全完成,就会发生类似于合并的动作(到底要将任务细化到什么粒度,完全看实际场景和自己对问题的理解)。下面用段简单的代码米说明Join 的使用。

thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。


img_18ca9625083eec946df53f16518b075f.png
package com.sss.test;

import java.util.Random;

/**
 * @author Shusheng Shi
 */
public class ThreadJoinTest {
    static class Computer extends Thread {
        private int start;
        private int end;
        private int result;
        private int[] array;

        public Computer(int[] array, int start, int end) {
            this.array=array;
            this.start=start;
            this.end=end;
        }

        @Override
        public void run() {
            for (int i=start; i < end; i++) {
                result+=array[i];
            }

            if (result < 0) {
                result&=Integer.MAX_VALUE;
            }

        }

        public int getResult() {
            return result;

        }
    }

    private final static int COUNTER=10000000;

    public static void main(String[] args) throws InterruptedException {
        int[] array=new int[COUNTER];
        Random random=new Random();
        for (int i=0; i < COUNTER; i++) {
            array[i]=Math.abs( random.nextInt() );
        }
        long start=System.currentTimeMillis();
        Computer c1=new Computer( array, 0, COUNTER );
        Computer c2=new Computer( array, COUNTER / 2, COUNTER );
        c1.start();
        c2.start();
        c1.join();
        c2.join();
        System.out.println( System.currentTimeMillis() - start );
        System.out.println( (c1.getResult() + c2.getResult()) & Integer.MAX_VALUE );
    }
}

这个例子或许不太好,只是1000 万个随机数叠加,为了防此CPU计算过快,在计算中增加一些判定操作,最后再将计算完的两个值输出,也输出运算时间。如果在有多个CPU的机器上做测试,就会发现数据量大时,多个线程计算具有优势,但是这个优势非常小,
而且在数据量较小的情况下,单线程会更快些。为何单线程可能会更快呢?
最主要的原因是线程在分配时就有开销(每个线程的分配过程本身就高要执行很多条底层代码,这些代码的执行相当于很多条CPU 叠加运算的指令),Join 操作过程还有其他的各种开销。
如果尝试将每个线程叠加后做一些其他的操作,例如IO读写、字符串处理等操作,多线程的优势就出来了,因为这样总体计算下来后,线程的创建时间是可以被忽略

所以我们在考量系统的综合性能时不能就一一个点或某种测试就轻易得出一一个最终结论,定要考虑更多的变动因素。

那么使用多线程带来更多的是上下文切换的开销,多线程操作的共享对象还会有锁瓶
否则就是非线程安全的。
颈,
综合考量各种开销因素、时间、空间,
最后利用大量的场景测试来证明推理是有
指导性的,如果只是一味地为了用多线程而使用多线程,则往往很多事情可能会适得
其反
Join5 ?是语法层面的线程合并,其实它更像是当前线程处于BLOCKEN 状态时去等待
I :他线程结束的事件,而且是逐个去Join。换句话说,Join 的顺序并不一一定是线程真正结
束的顺序,要保证线程结束的顺J 字性,它还无法实现,即使在本例中它也不是唯一的实现
方式,本章后面会提到许多基于并发编程工具的方式来实现会更加理想,管理也会更加体
系化,能适应更多的业务场景需求。

目录
相关文章
|
6天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
7天前
|
安全 Java 开发者
深入理解Java并发编程:线程安全与性能优化
【4月更文挑战第9天】本文将深入探讨Java并发编程的核心概念,包括线程安全和性能优化。我们将详细解析Java中的同步机制,包括synchronized关键字、Lock接口以及并发集合等,并探讨它们如何影响程序的性能。此外,我们还将讨论Java内存模型,以及它如何影响并发程序的行为。最后,我们将提供一些实用的并发编程技巧和最佳实践,帮助开发者编写出既线程安全又高效的Java程序。
20 3
|
8天前
|
Java
Java 并发编程:深入理解线程池
【4月更文挑战第8天】本文将深入探讨 Java 中的线程池技术,包括其工作原理、优势以及如何使用。线程池是 Java 并发编程的重要工具,它可以有效地管理和控制线程的执行,提高系统性能。通过本文的学习,读者将对线程池有更深入的理解,并能在实际开发中灵活运用。
|
6天前
|
算法 Java 开发者
Java中的多线程编程:概念、实现与性能优化
【4月更文挑战第9天】在Java编程中,多线程是一种强大的工具,它允许开发者创建并发执行的程序,提高系统的响应性和吞吐量。本文将深入探讨Java多线程的核心概念,包括线程的生命周期、线程同步机制以及线程池的使用。接着,我们将展示如何通过继承Thread类和实现Runnable接口来创建线程,并讨论各自的优缺点。此外,文章还将介绍高级主题,如死锁的预防、避免和检测,以及如何使用并发集合和原子变量来提高多线程程序的性能和安全性。最后,我们将提供一些实用的性能优化技巧,帮助开发者编写出更高效、更稳定的多线程应用程序。
|
5天前
|
Java
Java中ReentrantLock中tryLock()方法加锁分析
Java中ReentrantLock中tryLock()方法加锁分析
8 0
|
4天前
|
安全 算法 Java
深入理解Java并发编程:线程安全与性能优化
【4月更文挑战第11天】 在Java中,高效的并发编程是提升应用性能和响应能力的关键。本文将探讨Java并发的核心概念,包括线程安全、锁机制、线程池以及并发集合等,同时提供实用的编程技巧和最佳实践,帮助开发者在保证线程安全的前提下,优化程序性能。我们将通过分析常见的并发问题,如竞态条件、死锁,以及如何利用现代Java并发工具来避免这些问题,从而构建更加健壮和高效的多线程应用程序。
|
8天前
|
Java
Java并发编程:深入理解线程池
【4月更文挑战第7天】在现代软件开发中,多线程编程已经成为一种不可或缺的技术。为了提高程序性能和资源利用率,Java提供了线程池这一强大工具。本文将深入探讨Java线程池的原理、使用方法以及如何根据实际需求定制线程池,帮助读者更好地理解和应用线程池技术。
15 0
|
2天前
|
Java 程序员 编译器
Java中的线程同步与锁优化策略
【4月更文挑战第14天】在多线程编程中,线程同步是确保数据一致性和程序正确性的关键。Java提供了多种机制来实现线程同步,其中最常用的是synchronized关键字和Lock接口。本文将深入探讨Java中的线程同步问题,并分析如何通过锁优化策略提高程序性能。我们将首先介绍线程同步的基本概念,然后详细讨论synchronized和Lock的使用及优缺点,最后探讨一些锁优化技巧,如锁粗化、锁消除和读写锁等。
|
3天前
|
Java
探秘jstack:解决Java应用线程问题的利器
探秘jstack:解决Java应用线程问题的利器
13 1
探秘jstack:解决Java应用线程问题的利器
|
3天前
|
Java 调度 开发者
Java 21时代的标志:虚拟线程带来的并发编程新境界
Java 21时代的标志:虚拟线程带来的并发编程新境界
14 0