JAVA线程池使用

线程池的建立

ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("xxx-thread-%d").build();

ExecutorService executor = new ThreadPoolExecutor(16, 
                                                  32, 
                                                  60000L, 
                                                  TimeUnit.SECONDS, 
                                                  new LinkedBlockingQueue<Runnable>(200), 
                                                  namedThreadFactory, 
                                                  new DiscardOldestPolicy());
复制代码

ThreadPoolExecutor构造函数说明

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) {
            throw new IllegalArgumentException();
        }
        if (workQueue == null || threadFactory == null || handler == null){
            throw new NullPointerException();
        }
        this.acc = System.getSecurityManager() == null ? null : AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
复制代码

corePoolSize

保持在池中的线程数,即便它们是空闲的; 设置{@code allowCoreThreadTimeOut},容许线程数低于corePoolSize时,线程也由于空闲而终止。java

maximumPoolSize

池中容许的最大线程数bash

keepAliveTime

当线程数大于corePoolSize时,多余的空闲线程等待新任务的最大时间,超过此时间会被回收。ide

unit

keepAliveTime的时间单位函数

workQueue

用于在任务执行前保存任务的队列。这个队列将只包含{@code execute}方法提交的{@code Runnable}任务。ui

threadFactory

执行程序建立新线程时使用的线程工厂this

handler

RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采起一种策略处理提交的新任务。spa

四种默认的饱和策略

AbortPolicy

默认的饱和策略,直接抛出java.util.concurrent.RejectedExecutionException异常
复制代码

CallerRunsPolicy

任务被拒绝添加后,会调用当前线程池的所在的线程去执行被拒绝的任务。这个策略的缺陷就是可能会阻塞主线程。
复制代码

DiscardPolicy

让被线程池拒绝的任务直接抛弃,不会抛异常也不会执行。
复制代码

DiscardOldestPolicy

当任务被拒绝添加时,会抛弃任务队列中最早加入队列的,再把这个新任务添加进去。
复制代码

自定义饱和策略

  • 实现java.util.concurrent.RejectedExecutionHandler接口
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author 
 * @version 1.0.0
 * @Description  舍弃队列中最早加入的五条任务,并将新的任务加入队尾
 * @date 2020/6/2 21:25
 * @since 1.8
 */
public class MyRejectedPolicy implements RejectedExecutionHandler {

    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        if (!executor.isShutdown()){
            executor.getQueue().poll();
            executor.getQueue().poll();
            executor.getQueue().poll();
            executor.getQueue().poll();
            executor.getQueue().poll();
            executor.getQueue().offer(r);
        }
    }
}
复制代码
相关文章
相关标签/搜索