美文网首页线程池Java 杂谈
java线程池自动扩容

java线程池自动扩容

作者: 爱吃鱼aichiyu | 来源:发表于2018-01-26 14:45 被阅读22次

线程池构造方法有几个重要参数:

public ThreadPoolExecutor(int corePoolSize,//核心线程数
                              int maximumPoolSize,//最大线程数
                              long keepAliveTime,//当线程数大于核心线程数时,空闲线程存活时间
                              TimeUnit unit,//空闲时间单位
                              BlockingQueue<Runnable> workQueue//任务大于线程池数量时,用于保存任务的队列
) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

当线程池核心数量不够时,新加入的任务会被存放在队列中,如果队列存满了,线程池会创建更多的线程,直到maximumPoolSize。如果还不足以处理新的任务,则面临一个丢弃策略,默认的丢弃策略是抛异常!
常用的Executors.newCachedThreadPool()和Executors.newFixedThreadPool(n),它的队列都是Integer.MAX_VALUE,所以maximumPoolSize和keepAliveTime参数就没有意义了。
如果要自己实现一个线程自动扩容方案呢?以下代码供大家测试探讨

/**
 * Created on 2018/1/26 12:55
 * <p>
 * Description: [线程池自动扩容]
 * <p>
 * Company: [xxx]
 *
 * @author [aichiyu]
 */
public class TestAutoAdjustThreadPool {

    /**
     * 队列阈值,超过此值则扩大线程池
     */
    private static final int MAX_QUEUE_SIZE = 100;

    /**
     * 每次扩容自动增加线程数
     */
    private static final int PER_ADD_THREAD = 10;

    /**
     * 监控积压时间频率
     */
    private static final int MONITOR_DELAY_TIME = 1;

    private ScheduledExecutorService scheduledExecutorService ;

    private ThreadPoolExecutor executor ;


    public void start(){
        executor =new ThreadPoolExecutor(10, 100,
                60L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>());
        scheduledExecutorService = new ScheduledThreadPoolExecutor(10, new BasicThreadFactory.Builder().namingPattern("mq-monitor-schedule-pool-%d").daemon(true).build());
        scheduledExecutorService.scheduleWithFixedDelay(() -> {
            System.out.println("当前线程池状态!"+executor);
            //当队列大小超过限制,且jvm内存使用率小于80%时扩容,防止无限制扩容
            if(executor.getQueue().size() >= MAX_QUEUE_SIZE && executor.getPoolSize()< executor.getMaximumPoolSize() && getMemoryUsage()<0.8){
                System.out.println("线程池扩容!"+executor);
                executor.setCorePoolSize(executor.getPoolSize() + PER_ADD_THREAD);
            }
            //当队列大小小于限制的80%,线程池缩容
            if(executor.getPoolSize() > 0  && executor.getQueue().size() < MAX_QUEUE_SIZE * 0.8  ){
                System.out.println("线程池缩容!"+executor);
                executor.setCorePoolSize(executor.getPoolSize() - PER_ADD_THREAD);
            }


        }, MONITOR_DELAY_TIME, MONITOR_DELAY_TIME, TimeUnit.SECONDS);
    }

    public void stop() throws InterruptedException {
        executor.shutdown();
        while (!executor.awaitTermination(1,TimeUnit.SECONDS)){
            //等待线程池中任务执行完毕
        }
        scheduledExecutorService.shutdown();
    }

    public <T> Future<T> submit(Callable<T> task) {
        return executor.submit(task);
    }
    public Future<?> submit(Runnable task) {
        return executor.submit(task);
    }


    /**
     * 获取jvm内存使用率
     * @return
     */
    public static double getMemoryUsage() {
        return (double) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / Runtime.getRuntime().maxMemory();
    }


    public static void main(String[] args) throws InterruptedException {
        TestThreadPoolAutoExpand pool = new TestThreadPoolAutoExpand();
        pool.start();
        for (int i = 0; i < 1000; i++) {
            pool.submit(()->{
                System.out.println(Thread.currentThread()+" execute!~~");
                try {
                    Thread.sleep(1500L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        pool.stop();
    }
}

相关文章

  • java线程池自动扩容

    线程池构造方法有几个重要参数: 当线程池核心数量不够时,新加入的任务会被存放在队列中,如果队列存满了,线程池会创建...

  • 6. ThreadPool.h

    线程池,这个线程池暂时不具有自动扩容缩小的动能。 逻辑 正常的线程池的线是这个样子的。 创建一个线程池对象, 执行...

  • 【转载】线程池-2

    线程池基本调度功能。 线程池自动扩容缩容。 队列缓存线程。 关闭线程池。 这些功能,最后也留下了三个待实现的 fe...

  • Java线程池使用说明

    Java线程池使用说明 线程池的作用:线程池作用就是限制系统中执行线程的数量。根据系统的环境情况,可以自动或手动设...

  • 分析jdk-1.8-ForkJoinPool实现原理(上)

    Java并发编程源码分析系列: 分析Java线程池的创建 分析Java线程池执行原理 分析Java线程池Calla...

  • 分析jdk-1.8-ForkJoinPool实现原理(下)

    Java并发编程源码分析系列: 分析Java线程池的创建 分析Java线程池执行原理 分析Java线程池Calla...

  • 分析ReentrantLock的实现原理

    Java并发编程源码分析系列: 分析Java线程池的创建 分析Java线程池执行原理 分析Java线程池Calla...

  • 分析CountDownLatch的实现原理

    Java并发编程源码分析系列: 分析Java线程池的创建 分析Java线程池执行原理 分析Java线程池Calla...

  • java基础-多线程

    java线程池的实现 ThreadPoolExecutor java线程池几个参数 corePoolSize当线程...

  • 【并发】Java线程池的相关知识

    java线程池 是什么 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。...

网友评论

    本文标题:java线程池自动扩容

    本文链接:https://www.haomeiwen.com/subject/bioiaxtx.html