确保Java程序main线程最后结束的几种方法

Java Q&A Hub 使用 GPT-4o-mini 回答

问题:

Java面试题之多线程 你如何确保main()方法所在的线程是Java程序最后结束的线程?

回答:

在Java中,确保main()方法所在的线程是程序最后结束的线程,可以通过以下几种方式实现:

1. 使用Thread.join()

可以在main()方法中启动其他线程,并在这些线程完成后调用join()方法,确保main()线程在所有其他线程完成后再结束。

public class MainThreadExample {
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            // 执行一些任务
            System.out.println("Thread 1 is running");
        });

        Thread thread2 = new Thread(() -> {
            // 执行一些任务
            System.out.println("Thread 2 is running");
        });

        thread1.start();
        thread2.start();

        try {
            // 等待线程1和线程2完成
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Main thread is ending");
    }
}

2. 使用CountDownLatch

CountDownLatch可以用于等待多个线程完成后再继续执行main()线程。

import java.util.concurrent.CountDownLatch;

public class MainThreadExample {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(2); // 需要等待的线程数

        Thread thread1 = new Thread(() -> {
            // 执行一些任务
            System.out.println("Thread 1 is running");
            latch.countDown(); // 完成后减少计数
        });

        Thread thread2 = new Thread(() -> {
            // 执行一些任务
            System.out.println("Thread 2 is running");
            latch.countDown(); // 完成后减少计数
        });

        thread1.start();
        thread2.start();

        latch.await(); // 等待所有线程完成
        System.out.println("Main thread is ending");
    }
}

3. 使用ExecutorService

使用ExecutorService可以更方便地管理线程,并在所有任务完成后关闭服务。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainThreadExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        executorService.submit(() -> {
            // 执行一些任务
            System.out.println("Task 1 is running");
        });

        executorService.submit(() -> {
            // 执行一些任务
            System.out.println("Task 2 is running");
        });

        executorService.shutdown(); // 不再接受新任务
        try {
            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); // 等待所有任务完成
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Main thread is ending");
    }
}

总结

以上方法都可以确保main()方法所在的线程在所有其他线程完成后再结束。选择哪种方法取决于具体的需求和场景。使用join()方法是最直接的方式,而CountDownLatchExecutorService提供了更灵活的线程管理能力。