【Java-多线程】如何提交一个线程到线程池?

要将线程提交到线程池,主要通过Java的ExecutorService接口实现。以下是具体步骤和原理说明:


一、核心步骤

  1. 创建线程池

    ExecutorService executor = Executors.newFixedThreadPool(4); // 创建固定4线程的池
    
  2. 定义任务

    // Runnable接口(无返回值)
    Runnable task = () -> System.out.println("Runnable任务执行");
    
    // Callable接口(有返回值)
    Callable<String> callableTask = () -> {
        return "Callable任务结果";
    };
    
  3. 提交任务

    executor.execute(task); // 提交Runnable任务(无返回值)
    
    Future<String> future = executor.submit(callableTask); // 提交Callable任务(有返回值)
    
  4. 处理结果

    try {
        String result = future.get(); // 阻塞获取结果
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    
  5. 关闭线程池

    executor.shutdown(); // 平缓关闭(等待已提交任务完成)
    

二、关键区别

方法 参数类型 返回值 异常处理
execute() Runnable 直接抛出(需自行捕获)
submit() Runnable/Callable Future 封装在Future中

三、故事示例

场景:快递公司仓库(线程池)有4个分拣员(线程)。

  1. 普通包裹(Runnable任务)直接分拣,无需回执
  2. 贵重包裹(Callable任务)需要签收回执(Future)

代码实现

public class ThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService warehouse = Executors.newFixedThreadPool(4);
        
        // 普通快递(无返回)
        warehouse.execute(() -> {
            System.out.println("分拣普通包裹:" + Thread.currentThread().getName());
        });
        
        // 贵重快递(需回执)
        Future<String> receipt = warehouse.submit(() -> {
            System.out.println("处理贵重包裹:" + Thread.currentThread().getName());
            return "签收凭证-"+UUID.randomUUID();
        });
        
        try {
            System.out.println("获取回执:" + receipt.get(2, TimeUnit.SECONDS));
        } catch (Exception e) {
            System.out.println("包裹异常:" + e.getMessage());
        } finally {
            warehouse.shutdown();
        }
    }
}

四、常见问题处理

  1. 线程池满时策略

    • 默认抛出RejectedExecutionException
    • 可通过自定义线程池修改策略:
      new ThreadPoolExecutor(..., new LinkedBlockingQueue<>(10), 
          new ThreadPoolExecutor.CallerRunsPolicy());
      
  2. 异常捕获技巧

    executor.submit(() -> {
        try {
            // 业务代码
        } catch (Exception e) {
            System.out.println("捕获到异常:" + e);
        }
    });
    

五、思维导图

提交任务到线程池
创建线程池
Executors工厂类
newFixedThreadPool
newCachedThreadPool
newSingleThreadExecutor
定义任务类型
Runnable接口
Callable接口
提交方式选择
execute-无返回
submit-返回Future
Future.get获取结果
阻塞等待
超时设置
关闭线程池
shutdown平缓关闭
shutdownNow立即终止

总结:通过execute()提交简单任务,submit()处理需要结果的任务,始终记得关闭线程池。理解Future机制是掌握异步编程的关键。

你可能感兴趣的:(大白话说Java,java,开发语言)