官方及自定义线程池

Posted 劲火星空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了官方及自定义线程池相关的知识,希望对你有一定的参考价值。

一、官方



1、ThreadPoolExecutor


ThreadPoolExecutor有四个重载的构造方法,我们这里来说说参数最多的那一个重载的构造方法,这样大家就知道其他方法参数的含义了,如下:

public ThreadPoolExecutor(int corePoolSize,  
                              int maximumPoolSize,  
                              long keepAliveTime,  
                              TimeUnit unit,  
                              BlockingQueue<Runnable> workQueue,  
                              ThreadFactory threadFactory,  
                              RejectedExecutionHandler handler)   
这里是7个参数(我们在开发中用的更多的是5个参数的构造方法),OK,那我们来看看这里七个参数的含义:


corePoolSize:  线程池中核心线程的数量

maximumPoolSize:  线程池中最大线程数量

keepAliveTime: 非核心线程的超时时长,当系统中非核心线程闲置时间超过keepAliveTime之后,则会被回收。如果ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,则该参数也表示核心线程的超时时长

unit: 第三个参数的单位,有纳秒、微秒、毫秒、秒、分、时、天等

workQueue: 线程池中的任务队列,该队列主要用来存储已经被提交但是尚未执行的任务。存储在这里的任务是由ThreadPoolExecutor的execute方法提交来的。

threadFactory:  为线程池提供创建新线程的功能,这个我们一般使用默认即可

handler: 拒绝策略,当线程无法执行新任务时(一般是由于线程池中的线程数量已经达到最大数或者线程池关闭导致的),默认情况下,当线程池无法处理新线程时,会抛出一个RejectedExecutionException。



2、线程池的种类


(1)newFixedThreadPool() : 
作用:该方法返回一个固定线程数量的线程池,该线程池中的线程数量始终不变,即不会再创建新的线程,也不会销毁已经创建好的线程,自始自终都是那几个固定的线程在工作,所以该线程池可以控制线程的最大并发数。 
栗子:假如有一个新任务提交时,线程池中如果有空闲的线程则立即使用空闲线程来处理任务,如果没有,则会把这个新任务存在一个任务队列中,一旦有线程空闲了,则按FIFO方式处理任务队列中的任务。

(2)newCachedThreadPool() : 
作用:该方法返回一个可以根据实际情况调整线程池中线程的数量的线程池。即该线程池中的线程数量不确定,是根据实际情况动态调整的。 
栗子:假如该线程池中的所有线程都正在工作,而此时有新任务提交,那么将会创建新的线程去处理该任务,而此时假如之前有一些线程完成了任务,现在又有新任务提交,那么将不会创建新线程去处理,而是复用空闲的线程去处理新任务。那么此时有人有疑问了,那这样来说该线程池的线程岂不是会越集越多?其实并不会,因为线程池中的线程都有一个“保持活动时间”的参数,通过配置它,如果线程池中的空闲线程的空闲时间超过该“保存活动时间”则立刻停止该线程,而该线程池默认的“保持活动时间”为60s。

(3)newSingleThreadExecutor() : 
作用:该方法返回一个只有一个线程的线程池,即每次只能执行一个线程任务,多余的任务会保存到一个任务队列中,等待这一个线程空闲,当这个线程空闲了再按FIFO方式顺序执行任务队列中的任务。

(4)newScheduledThreadPool() : 
作用:该方法返回一个可以控制线程池内线程定时或周期性执行某任务的线程池。

(5)newSingleThreadScheduledExecutor() : 
作用:该方法返回一个可以控制线程池内线程定时或周期性执行某任务的线程池。只不过和上面的区别是该线程池大小为1,而上面的可以指定线程池的大小。



3、使用
    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
    ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
    ScheduledExecutorService singleThreadScheduledPool = Executors.newSingleThreadScheduledExecutor();



二、自定义

public class ThreadManager 

    private ThreadManager();
    private static ThreadManager instance= new ThreadManager();
    private ThreadPoolProxy longPoolProxy;
    private ThreadPoolProxy shortPoolProxy;
    public static ThreadManager getInstance()
        return instance;
    
    /**
     * 长线程池
     * @return
     */
    public synchronized ThreadPoolProxy createLongPool()
        if (longPoolProxy == null) 
            //(int corePoolSize 线程池大小, int maximumPoolSize 最大值, long keepAliveTime 存活时间)
            longPoolProxy = new ThreadPoolProxy(5, 5, 5000);
        
        return longPoolProxy;
    
    /**
     * 短线程池
     * @return
     */
    public synchronized ThreadPoolProxy createShortPool()
        if (shortPoolProxy == null) 
            shortPoolProxy = new ThreadPoolProxy(3, 3, 5000);
        
        return shortPoolProxy;
    

    public class ThreadPoolProxy
        private ThreadPoolExecutor pool;
        private int corePoolSize; //线程数
        private int maximumPoolSize; //线程满了后额外开的线程窗口
        private long keepAliveTime;//没有线程执行时存活时间
        public ThreadPoolProxy(int corePoolSize,int maximumPoolSize, long keepAliveTime)
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.keepAliveTime = keepAliveTime;
        

        /**
         * 执行线程
         * @param runnable
         */
        public void execute(Runnable runnable)
            if (pool == null) 
                //最多可有多少个线程排队
                BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(10);
                pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, workQueue);
            
            pool.execute(runnable);
        
        /**
         * 取消线程
         * @param runnable
         */
        public void cancel(Runnable runnable)
            if (pool != null) 
                pool.remove(runnable);
            
        
    


使用方法如下:
ThreadManager.getInstance().createLongPool().execute(new Runnable() 
            @Override
            public void run() 
                //SystemClock.sleep(2000);
                final LoadResult result = loadFromServer();
                if (result != null) 
                    Util.runOnUiThread(new Runnable() 
                        @Override
                        public void run() 
                            currentState = result.getValue();
                            showPages();
                        
                    );
                
            
        );





以上是关于官方及自定义线程池的主要内容,如果未能解决你的问题,请参考以下文章

Java ExecutorService四种线程池及自定义ThreadPoolExecutor机制

React fiber原理解析及自定义实现

java线程池

线程池任务执行器,,,最大池大小是多少,核心池大小可以在java中定义

python 异常继承关系及自定义异常的实现

线程池 - java.util.concurrent.RejectedExecutionException