Java如何使用异步编排任务和线程池?

本文详细讲解了线程池的创建与管理,包括核心参数解析及常见线程池类型。深入探讨了CompletableFuture异步编排,涵盖runAsync、whenComplete、handleAsync等方法,并通过实例演示了线程串行化、组合任务等功能,最后提供了配置线程池和异步编排的实际应用案例。

一、如何创建线程池?

1、七大参数介绍

1)corePoolSize

       核心线程数,一直存在线程池中(除非设置了allowCoreThreadTimeOut),创建好就等待就绪,去执行任务

2)maximumPoolSize

       最大线程数,设置最大线程数是为了控制资源

3)keepAliveTime

       存活时间,如果当前的线程数大于核心线程数,并且线程空闲的时间大于存活时间了,则会执行释放线程的操作。(释放的数量为:maximumPoolSize - corePoolSize)

4)unit

       时间单位

5)workQueue

       阻塞队列,如果任务有很多,就会将目前多的任务放到队列中,当有空闲的线程时,就会从队列中取出新的任务继续执行。

6)threadFactory

       线程的创建工厂

7)handler

       拒绝策略,如果队列满了,按照我们指定的拒绝策略拒绝执行任务


有哪些拒绝策略?

  1. DiscardOldestPolicy
       如果有新的任务进来就会丢去最旧的未执行的任务

  2. AbortPolicy
       直接丢弃新任务,抛出异常

  3. CallerRunsPolicy
       如果有新任务进来,直接调用run()方法,同步执行操作


  1. DiscardPolicy
       直接丢弃新进来的任务,不会抛出异常

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)

// 常见的创建线程的方式
// 1)Executors . newCachedThreadApol() // 核心为0,所有都可回收的线程池
public static ExecutorService newCachedThreadPool() {
   
   
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
// 2)Ехесutоrѕ . nеwFіхеdТhrеаdРооl() 固定大小的线程池,不会过期
public static ExecutorService newFixedThreadPool(int nThreads) {
   
   
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
// 3)Executors . newScheduledThreadPool() 定时任务的线程池
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
   
   
        return new ScheduledThreadPoolExecutor(corePoolSize);
}
// 4)Executors . newSingleThreadExecutor() 单线程的线程池,后台从队列中获取任务,一个一个执行
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
   
   
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>(),
                                    threadFactory));
}

问:一个corePoolSize=7 maximumPoolSize=20 workQueue=50的线程池,如果本次有100个并发进来,是如何执行的?

       答:7个会立即被执行,50个会进入队列,然后会另外开13个新的线程,剩余的30个线程就需要看当前线程池的拒绝策略了。


二、CompletableFeture异步编排

1、runAsync 创建异步对象的方式

	// 1)无返回值的异步操作
	public static CompletableFuture<Void> runAsync(Runnable runnable) {
   
   
	        return asyncRunStage(asyncPool, runnable);
	}
	// 2)无返回值的异步操作,可指定线程池
	public static CompletableFuture<Void> runAsync(Runnable runnable,
	                                                   Executor executor) {
   
   
	        return asyncRunStage(screenExecutor(executor), runnable);
	}
	
	// 3)有返回值的异步操作
	public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
   
   
	        return asyncSupplyStage(asyncPool, supplier);
	}
	
	// 4)有返回值的异步操作,可指定线程池
	public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
	                                                       Executor executor) {
   
   
	        return asyncSupplyStage(screenExecutor(executor), supplier);
	}

2、whenComplete 计算完成时回调的方法

1)方法介绍
	// 上一个异步完成时执行该方法,和上一个任务用同一个线程
	public CompletableFuture<T> whenComplete(
	    BiConsumer<? super T, ? super Throwable
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柯十一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值