`

主线程结束子线程也不执行了,很奇怪,按理不应该这样

 
阅读更多
引用
最近在测试使用多线程从数据库中读数据,所有子线程结束后,再讲汇总的数据保存到文件中。发现了一个问题,总是会出现这样一种情况:主线程结束后,子线程中的代码还没有执行结束就不再执行了,只执行了其中的一部分。

找了各种资料,都在说主线程结束后,如果子线程不是守护线程,子线程将不会受到影响,继续执行。我这里的线程明明不是守护线程,所以还是很奇怪。

最终终于找出原因了,原来是因为junit单元测试的原因,如果把这段代码放到main方法中执行,每次都是好的。

我还学到了CyclicBarrier这个类的使用方法和场景,这个类在多线程时还是非常有用的。比如:
起10个线程分别取从数据库中以分页的方式去查数据,当10个线程都执行结束后,将总的查询数据写入的数据库中。这个时候如何保证所有线程都执行结束的这个时间点,就可以使用CyclicBarrier。

CyclicBarrier:同步辅助类。一组线程相互等待,全部执行结束后,会唤醒CyclicBarrier指定的同步线程,执行最终的统计工作。


public class CountThread extends Thread {

    public CountThread(int count, CyclicBarrier cyclicBarrier) {
        this.count = count;
        this.cyclicBarrier = cyclicBarrier;
    }

    private int count;
    private CyclicBarrier cyclicBarrier;

    public void run() {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.out.println(count);
        try {
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }

    }

}



public class SumTaskThread implements Runnable {

    @Override
    public void run() {
        System.out.println("****************汇总*******************");
    }

}



public static void main(String[] args) {
        test1();
    }

    public static void test1() {
        // 同步辅助类,当所有的10个子线程都指向结束后会指向SumTaskThread线程
        CyclicBarrier cyclicBarrier = new CyclicBarrier(10, new SumTaskThread());

        for (int i = 1; i <= 10; i++) {
            new CountThread(i, cyclicBarrier).start();
        }

        System.out.println("主线程执行结束");
    }
分享到:
评论

相关推荐

    JAVA主线程等待子线程执行完毕再执行[参照].pdf

    JAVA 主线程等待子线程执行完毕再执行 JAVA 中的线程控制是非常重要的一部分,而在实际开发中,我们经常会遇到需要主线程等待子线程执行完毕再执行的情况。这种情况下,我们可以使用两种方式来实现:主动式和被动式...

    Handler主线程于子线程,子线程与子线程,主线程到子线程消息传递

    Handler消息传递详解,子线程到子线程,主线程到子线程,子线程到主线程 三种消息,Looper,Handler工作机制详解 https://blog.csdn.net/shoneworn/article/details/80447651

    Java简单实现“主线程等待所有子线程完成再继续”

    有时我们可能需要设计程序,使得主线程在执行过程中能够等待所有子线程完成后再继续执行。这种需求常见于需要同步多个并行任务或者在主任务结束前确保所有子任务已经处理完毕的场景。本文将详细解释如何使用Java实现...

    Java主线程等待子线程执行完毕

    Java 主线程等待子线程执行完毕 Java 中的多线程编程是非常重要的一部分,特别是在需要并发执行多个任务的情况下。然而,在某些情况下,我们需要等待所有子线程执行完毕后再继续执行主线程的剩余动作。这时,我们...

    主线程等待子线程结束代码

    我在工作的过程中遇到一个问题,需要主线程等等所有子线程执行完后再做某件事情,在网上找了很多代码,都没有真正解决这个问题. 现在我解决了这个问题,把代码共享出来供大家参考. 代码中有注释和注意事项,相信大家看过...

    C#子线程执行完后通知主线程的方法

    在C#编程中,多线程是常见的并发执行方式,其中主线程通常负责应用程序的主逻辑,而子线程则可以执行一些独立的任务。当子线程完成其工作后,有时需要通知主线程以便进行下一步操作。本文将详细介绍如何在C#中实现...

    QT多线程编程、主线程与子线程交互数据

    需要注意的是,所有涉及GUI操作的代码必须在主线程中执行,因为QT的GUI是线程不安全的。 在VS2017中,可以使用QT Creator插件或者直接在VS中配置QT项目,来开发QT多线程程序。配置步骤包括安装QT插件、添加QT库和...

    python爬虫-08-主线程会等待子线程执行结束再结束.ev4.rar

    本教程重点讲解了在Python中如何处理主线程与子线程的关系,特别是主线程如何等待子线程执行完毕后再结束。 在Python中,多线程是一种并发执行的方式,可以提高程序的运行效率。`threading`模块提供了创建和管理...

    有关主线程和子线程

    - 也可以将定时器的创建放入子线程中,以避免影响主线程的性能。 #### NSOperationQueue - **任务队列**(`NSOperationQueue`): 是另一种线程管理和任务调度机制,允许开发者以队列的形式组织任务。 - 可以通过...

    C# 主线程显示数据,子线程获取数据

    在C# Winform应用开发中,主线程与子线程的协同工作是一项核心技能,尤其在处理耗时操作,如数据库查询、网络通信等时,更显得至关重要。本主题聚焦于如何利用“异步委托”在主线程中显示数据,同时在子线程中获取...

    如何从子线程更新主线程数据

    在多线程编程中,尤其是使用VC++进行开发时,如何有效地从子线程更新主线程的数据是一个重要的问题。这涉及到线程间通信(Thread Communication)的概念,它确保了不同线程之间的协作和数据同步。在Windows环境中,...

    python 零基础学习篇多任务编程线程5 主线程会等待子线程执行结束再结束 .mp4

    python 零基础学习篇

    android 主线程给子线程发送消息

    在Android应用开发中,主线程(也称为UI线程)主要负责处理用户界面的更新和交互,而子线程则通常用于执行耗时的操作,如网络请求、数据库操作等,以避免阻塞主线程,保证用户界面的流畅性。本示例"android 主线程给...

    子线程任务发生异常,主线程事务如何回滚

    在主线程中,我们可以使用 Future 对象来获取子线程的执行结果。如果子线程执行过程中发生异常,Future 对象将抛出异常。我们可以使用 try-catch 语句来捕获异常,并进行事务的回滚。 当子线程任务发生异常时,如何...

    主线程等待子多线程(无结果返回)执行完成再继续执行

    在Java中,主线程可以通过调用子线程的`join()`方法来等待该子线程结束。`join()`会阻塞当前线程(即主线程),直到被调用的子线程执行完毕。例如: ```java Thread childThread = new Thread(() -&gt; { // 子线程...

    android主线程、子线程及线程间通信方式测试app

    本文将深入探讨Android主线程(也称为UI线程)、子线程以及它们之间的通信方式,结合"android主线程、子线程及线程间通信方式测试app"的描述,我们将详细分析相关知识点。 1. **Android主线程**:主线程是应用程序...

    Qt主线程与次线程通信实例代码

    Qt主线程与次线程(也称为工作线程)的通信是一个重要的概念,它涉及到多线程编程和UI更新的正确处理。本实例代码提供了关于如何在Qt中实现线程间通信的示例,这对于提高应用性能和避免阻塞用户界面至关重要。 主线...

    QTimer在子线程里执行例子

    在多线程编程中,有时我们需要在子线程中使用定时器来执行某些任务,以避免阻塞主线程,提高程序的响应性和效率。`QTimer`在子线程中的使用涉及到Qt的线程模型和事件循环。下面我们将详细探讨如何在子线程中使用`...

    python主线程与子线程的结束顺序实例解析

    通常,如果主线程结束,而子线程还在执行,那么这些子线程的命运取决于它们是否被设定为守护线程(daemon)。 1. **主线程等待所有子线程执行完毕**: 当主线程创建的子线程不是守护线程时,主线程会等待这些子...

    C#子线程刷新主线程示例源码20121128

    C#子线程刷新主线程示例源码 功能介绍: 使用线程操作 1、实时显示当前时间 2、输入加数和被加数,自动出现... 使用了多线程实现了子线程刷新主线程 ,使用委托刷新主线程。 注意: 开发环境为Visual Studio 2012

Global site tag (gtag.js) - Google Analytics