【JUC —— 10 线程池 】

线程池是并发编程中的一个重要工具,可以有效地管理和调度线程。Java 提供了丰富的线程池实现和配置选项。

1. 线程池的三大方法

  1. execute(Runnable command)
    执行一个没有返回值的任务。适用于不需要返回结果的任务。
  2. submit(Callable<T> task)submit(Runnable task, T result)
    执行一个有返回值的任务,可以提交 CallableRunnable,并返回一个 Future 对象,用于获取任务的执行结果。
  3. invokeAll(Collection<? extends Callable<T>> tasks)
    执行一批任务,返回一批 Future 对象。所有任务执行完毕后,调用者可以获取每个任务的结果。
ExecutorService executor = Executors.newFixedThreadPool(2);
// execute
executor.execute(() -> System.out.println("Task executed"));
// submit
Future<String> future = executor.submit(() -> "Task result");


List<Callable<String>> tasks = Arrays.asList(
    () -> "Task 1 result",
    () -> "Task 2 result"
);
// invokeAll
List<Future<String>> futures = executor.invokeAll(tasks);

executor.shutdown();

2. 线程池的七大参数

创建线程池时,可以通过 ThreadPoolExecutor 类的构造函数指定以下七个参数:

  1. corePoolSize
    核心线程池大小,线程池在没有任务执行时也会维护这些线程。

  2. maximumPoolSize
    最大线程池大小,线程池能够容纳的最大线程数

  3. keepAliveTime
    非核心线程的空闲存活时间。当线程池中线程数量超过核心线程数量时,多余的线程在空闲时间超过 keepAliveTime 时会被销毁。

  4. unit
    keepAliveTime 的时间单位。

  5. workQueue
    任务队列,用于存储等待执行的任务

  6. threadFactory:
    线程工厂,用于创建新线程。

  7. handler:
    拒绝策略,当任务太多来不及处理时如何处理新任务。

ExecutorService executor = new ThreadPoolExecutor(
    2,                               // corePoolSize
    4,                               // maximumPoolSize
    60,                              // keepAliveTime
    TimeUnit.SECONDS,                // unit
    new LinkedBlockingQueue<>(10),   // workQueue
    Executors.defaultThreadFactory(),// threadFactory
    new ThreadPoolExecutor.AbortPolicy() // handler
);

3. 线程池的四种拒绝策略

  1. AbortPolicy(默认策略):抛出 RejectedExecutionException,阻止系统正常工作

  2. CallerRunsPolicy:由调用线程处理该任务。这种策略不会抛弃任务或抛出异常,但会阻塞提交任务的线程,直到可以提交任务

  3. DiscardPolicy:直接丢弃任务,不予处理,不抛出异常

  4. DiscardOldestPolicy:丢弃队列中最老的一个任务,并尝试重新提交当前任务

4. Executors 类

Java 的 Executors 工具类提供了几种方便的创建线程池的方法,这些方法封装了常用的 ThreadPoolExecutor 配置,简化了线程池的使用。以下是 Executors 创建线程池的几种方法:

1. newFixedThreadPool(int nThreads)

创建一个固定大小的线程池,线程池中的线程数量固定。

如果所有线程都在执行任务,新提交的任务会在队列中等待。

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

2. newCachedThreadPool()

创建一个可缓存的线程池。如果线程池中有空闲线程可以重用,则会重用这些线程;

如果所有线程都在执行任务,则会创建新的线程。空闲线程会在60秒后被终止和移除。

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

3. newSingleThreadExecutor()

创建一个单线程的线程池。

它确保所有任务在同一个线程中按顺序执行,适用于需要按顺序执行任务的场景。

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

4. newScheduledThreadPool(int corePoolSize)

创建一个支持定时及周期性任务执行的线程池。

适用于需要定期执行任务的场景。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }

public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }

通过灵活地配置线程池的参数和拒绝策略,可以在不同的应用场景下实现高效的任务调度和资源管理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值