等待线程终结

  • 场景 : 某个程序在其他操作前要初始化需要的资源
    在一个线程中运行初始化任务,在继续执行程序其他部分前等待此线程的终结。

  • 解决方案 : 使用 Thread 类的 join 方法
    当用一个线程对象调用此方法时,将挂起调用线程直掉被调用对象结束执行。

任务

实现上述场景

实现

  • 线程类

    • DataSourcesLoader
      • 在 run 方法开始、结束时输出时间
      • sleep 4 秒
            System.out.printf("Beginning data sources loading: %s\n",new Date());
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.printf("Data sources loading has finished: %s\n",new Date());
    
    • NetworkConnectionsLoader : 和 DataSourcesLoader 基本一样,只是 sleep 6 秒
  • 控制类 (Main)

    • 创建 DataSourcesLoader 类对象及对应的线程
        DataSourcesLoader dsLoader = new DataSourcesLoader();
        Thread dsThread = new Thread(dsLoader, "DataSourceLoader");
    
    • 创建 NetworkConnectionsLoader 类对象及对应的线程
        NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
        Thread ncThread = new Thread(ncLoader, "NetworkConnectionsLoader");
    
    • 启动线程后调用2个线程对象的 join 方法
        dsThread.start();
        ncThread.start();
    
        try {
            dsThread.join();
            ncThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
    • 最后输出时间供比较参考
        System.out.printf("Main: Configuration has been loaded: %s\n",new Date());
    

工作原理

运行此程序,您可看到 2 个线程对象都执行了。顺序如下:

  1. DataSourcesLoader 结束执行
  2. NetworkConnectionsLoader 结束执行
  3. 2个线程都结束了时,主线程对象继续执行并输出最终信息

了解更多

  • Java 还提供了另外 2 种形式的 join 方法
    • join(long milliseconds)
    • join(long milliseconds, long nanos)
  • 与 join() 方法的区别
    • join() 方法一直等待,直到被调用线程结束运行
    • 带参数的 join 方法:最多只等待指定时间