在 Java 中,线程池通常使用 ExecutorService 接口来管理。ExecutorService 接口提供了两种方法来提交任务:submit()execute()。它们之间的区别主要在于任务的返回值和异常处理。

  1. submit() 方法:

    • submit() 方法用于提交一个任务给线程池执行,并返回一个 Future 对象,通过这个对象可以获取任务的执行结果或者等待任务完成。
    • 如果任务执行成功,Future 对象的 get() 方法会返回任务的执行结果;如果任务抛出了异常,get() 方法会抛出 ExecutionException,其中包含原始异常的信息。
    • submit() 方法可以接受 CallableRunnable 或者其他类作为参数。
  2. execute() 方法:

    • execute() 方法用于提交一个不带返回值的任务给线程池执行,无法获取任务的执行结果。
    • 如果任务执行成功,则没有明确的方式来获取任务的执行结果;如果任务抛出了异常,它会被传递到线程池的未捕获异常处理器中进行处理。
    • execute() 方法只能接受 Runnable 类型的任务作为参数。

下面是一个示例代码,演示了 submit()execute() 方法的使用:

import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // 创建一个线程池
        ExecutorService executor = Executors.newFixedThreadPool(2);

        // 使用submit()提交任务
        Future<Integer> future = executor.submit(() -> {
            System.out.println("Callable task is running");
            return 123;
        });

        try {
            Integer result = future.get();
            System.out.println("Callable task result: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // 使用execute()提交任务
        executor.execute(() -> {
            System.out.println("Runnable task is running");
        });

        // 关闭线程池
        executor.shutdown();
    }
}

在这个示例中,我们首先创建了一个固定大小为2的线程池。然后,我们使用 submit() 方法提交了一个 Callable 任务,并通过 Future 对象获取了任务的执行结果。接着,我们使用 execute() 方法提交了一个 Runnable 任务。最后,我们调用 shutdown() 方法关闭了线程池。


在Java中有四种主要的线程池,分别是FixedThreadPoolCachedThreadPoolScheduledThreadPoolSingleThreadPool。下面给出每种线程池的简要介绍和示例代码:

  1. FixedThreadPool(固定大小线程池)
    • 创建固定数量的线程池,当有新的任务提交时,如果线程池中有空闲线程,则立即执行,否则将任务放入队列中等待执行。
    • 适用于需要控制线程数量的情况,例如服务器端的并发请求处理。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); // 创建一个固定大小为3的线程池
for (int i = 0; i < 10; i++) {
    fixedThreadPool.execute(() -> {
        System.out.println("Thread " + Thread.currentThread().getName() + " is executing task");
    });
}
fixedThreadPool.shutdown(); // 关闭线程池
  1. CachedThreadPool(可缓存线程池)
    • 根据需要创建新的线程,如果线程池中有空闲线程,则复用,否则创建新线程。
    • 适用于处理大量短期异步任务的情况,例如IO密集型任务。
ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); // 创建一个可缓存的线程池
for (int i = 0; i < 10; i++) {
    cachedThreadPool.execute(() -> {
        System.out.println("Thread " + Thread.currentThread().getName() + " is executing task");
    });
}
cachedThreadPool.shutdown(); // 关闭线程池
  1. ScheduledThreadPool(定时任务线程池)
    • 创建一个定时任务线程池,可以在指定的延迟之后执行任务,或者按固定的周期执行任务。
    • 适用于需要按计划执行任务的情况,例如定时任务调度。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2); // 创建一个大小为2的定时任务线程池
scheduledThreadPool.schedule(() -> {
    System.out.println("Scheduled task executed once after 3 seconds");
}, 3, TimeUnit.SECONDS);
scheduledThreadPool.scheduleAtFixedRate(() -> {
    System.out.println("Scheduled task executed every 2 seconds");
}, 0, 2, TimeUnit.SECONDS);
  1. SingleThreadExecutor(单线程线程池)
    • 创建一个单线程的线程池,所有任务按照顺序在同一个线程中执行。
    • 适用于需要顺序执行任务的情况,例如任务队列处理。
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); // 创建一个单线程的线程池
for (int i = 0; i < 5; i++) {
    singleThreadPool.execute(() -> {
        System.out.println("Thread " + Thread.currentThread().getName() + " is executing task");
    });
}
singleThreadPool.shutdown(); // 关闭线程池

这些是Java中常见的四种线程池及其示例代码,可以根据具体需求选择适合的线程池类型。

刚学java菜鸡,永劫无间蚀月,王者荣耀王者,金铲铲小铂金,第五人格菜鸡,原神开服玩家,星穹铁道菜鸡,崩坏的菜鸡,闪耀暖暖,和平精英,LOL,CSGO,以及三A大作收集者等等。。。