ThreadPoolExecutor自定义线程池的使用及同步化处理

参照官方api文档地址:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html

An ExecutorService that executes each submitted task using one of possibly several pooled threads, normally configured using Executors factory methods.

Thread pools address two different problems: they usually provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and managing the resources, including threads, consumed when executing a collection of tasks. Each ThreadPoolExecutor also maintains some basic statistics, such as the number of completed tasks.

To be useful across a wide range of contexts, this class provides many adjustable parameters and extensibility hooks. However, programmers are urged to use the more convenient Executors factory methods Executors.newCachedThreadPool() (unbounded thread pool, with automatic thread reclamation), Executors.newFixedThreadPool(int) (fixed size thread pool) and Executors.newSingleThreadExecutor() (single background thread), that preconfigure settings for the most common usage scenarios. Otherwise, use the following guide when manually configuring and tuning this class:

线程池解决了两个不同的问题:1.由于减少了每个任务的调用开销,使得在执行大量异步任务时,性能提升明显。2.统计信息:每个ThreadPoolExecutor维护一些基本统计信息,例如已完成任务的数量。

为了在广泛的上下文中有用,该类提供了许多可调整的参数和可扩展性钩子。Executors工厂方法针对最常见的使用场景预设了以下几种线程池:

Executors.newCachedThreadPool()(无限制线程池,具有自动线程回收)

Executors.newFixedThreadPool(int)(固定大小的线程池)

Executors.newSingleThreadExecutor()(单个后台线程)

还有Executors.newScheduledThreadPool(int);(调度线程池)

以上的几种预设线程池放在之后总结,本次来总结下自定义线程池的使用。

ThreadPoolExecutor提供了4个构造方法:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)

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

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

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

参数解释:

corePoolSize 核心线程数,线程池维护的初始线程数,一直保留

maximumPoolSize 最大线程数,线程池允许的最大线程数

keepAliveTime 空闲线程存活时间,当线程数>corePoolSize,超出的部分线程执行完毕后可在线程池中存活的时间

unit 存活时间单位

workQueue 工作队列,当添加线程任务时,没有空闲的可用线程,则会把任务放在该队列中

threadFactory 线程工厂类

handler 拒绝策略,当没有可用的空闲线程且工作队列也满了,此时会调用handler的rejectedExecution方法

        几种预定义的实现:

        AbortPolicy(默认):直接抛弃

        CallerRunsPolicy:用调用者的线程执行任务

        DiscardOldestPolicy:抛弃队列中最久的任务

        DiscardPolicy:抛弃当前任务

单例模式创建线程池对象&线程池监控:

package com.app.thread;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ThreadPoolManager
{
    private static final Logger LOG = LoggerFactory.getLogger(ThreadPoolManager.class);
    
    private volatile static ThreadPoolManager instance = null;
    
    private static final int CORE_POOL_SIZE = 200;
    
    // 线程池最大线程数
    private static final int MAX_POOL_SIZE = Integer.MAX_VALUE;
    
    // 空闲线程存活时间
    private static final long KEEP_ALIVE_TIME = 10L;
    
    // 存活时间单位
    private static final TimeUnit TIME_UNIT_SECOND = TimeUnit.MILLISECONDS;
    
    // 工作队列
    private static final LinkedBlockingQueue<Runnable> WORK_QUEUE = new LinkedBlockingQueue<Runnable>();
    
    // 线程池实例
    private final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TIME_UNIT_SECOND, WORK_QUEUE);
    
    private ThreadPoolManager()
    {
    }
    
    /**
     * 获取线程管理实例
     */
    public static ThreadPoolManager getInstance()
    {
        if (instance == null)
        {
            synchronized (ThreadPoolManager.class)
            {
                instance = new ThreadPoolManager();
            }
        }
        return instance;
    }
    
    /**
     * 线程池加入执行对象
     */
    public void addExcuteTask(Runnable run)
    {
        LOG.info("addExecuteTask Runnable in threadpool ");
        try
        {
            if (run != null)
            {
                threadPoolExecutor.execute(run);
            }
        }
        catch (Exception e)
        {
            LOG.error("Failed addExcuteTask run ", e);
        }
    }
    
    public void setAllowCoreThreadTimeout(boolean b)
    {
        threadPoolExecutor.allowCoreThreadTimeOut(b);
    }
    
    /**
     * 判断是否是最后一个任务
     */
    public boolean isTaskEnd()
    {
        if (threadPoolExecutor.getActiveCount() == 0)
        {
            return true;
        }
        else
            return false;
    }
    
    /**
     * 获取队列缓存大小
     */
    public int getQueueSize()
        throws Exception
    {
        return threadPoolExecutor.getQueue().size();
    }
    
    /**
     * 获取线程池当前线程数目
     */
    public int getPoolSize()
        throws Exception
    {
        LOG.info("get pool size");
        try
        {
            return threadPoolExecutor.getPoolSize();
        }
        catch (Exception e)
        {
            LOG.info("Fail to get thread pool size", e);
        }
        return 0;
    }
    
    /**
     * 获取已经完成的线程数目
     */
    public long getCompleteTaskCount()
        throws Exception
    {
        LOG.info("get complete task count in thread pool");
        try
        {
            return threadPoolExecutor.getCompletedTaskCount();
        }
        catch (Exception e)
        {
            LOG.info("Fail to get complete task count in thread pool", e);
        }
        return 0l;
    }
    
    /**
     * 初始化所有核心线程
     */
    public void initCoreThread()
    {
        try
        {
            threadPoolExecutor.prestartAllCoreThreads();
        }
        catch (Exception e)
        {
            LOG.info("Fail to init all core thread");
        }
    }
    
    /**
     * 关闭线程池
     */
    public void shutDown()
    {
        LOG.info("shut down thread pool");
        try
        {
            threadPoolExecutor.shutdown();
        }
        catch (Exception e)
        {
            LOG.error("Fail to shutdown threadpool! ", e);
        }
    }
    
    public Long getTaskCount()
        throws Exception
    {
        LOG.info("get  task count in thread pool");
        try
        {
            return threadPoolExecutor.getTaskCount();
        }
        catch (Exception e)
        {
            LOG.info("Fail to get  task count in thread pool", e);
        }
        return 0l;
    }
    
    public int getActiveTask()
        throws Exception
    {
        LOG.info("get  active task count in thread pool");
        try
        {
            return threadPoolExecutor.getActiveCount();
        }
        catch (Exception e)
        {
            LOG.info("Fail to get  active task count in thread pool", e);
        }
        return 0;
    }
    
    public int preStartAllCore()
    {
        return threadPoolExecutor.prestartAllCoreThreads();
    }
}

异步线程的同步化处理:

一些业务场景需要我们在某些数据处理完毕后才能进行下一步操作,若使用多线程处理“某些数据”,则需要我们想办法监控线程的执行状态(是否执行完毕)

提供以下思路:

新建一个线程数量监控的类ThreadCollector,定义两个记录线程数的变量ThreadCount(新增线程数量)、FinishedCount(已完成线程数量),操作这两个变量的线程同步的方法addOne(){ThreadCount++}、finishedOne(){FinishedCount++},以及判断线程是否执行完的方法hasAllFinished(){return ThreadCount==FinishedCount}

在调用多线程线程添加完线程后循环判断是否执行完毕,若执行完毕则结束循环进行下一步操作。

while (true)

{

if (threadCollector.hasAllFinished())

{

// 重置计数

...

break;

}

Thread.sleep(1000);

}

// 执行后续操作

...

完整资源联系获取--.

猜你喜欢

转载自blog.csdn.net/qq_34928194/article/details/106339123
今日推荐