java线程(三)

77 阅读4分钟

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」@[toc]

五.线程池

②.构造方法

ThreadPoolExecutor有四个参数不同的构造方法,其实都是用参数最多的那个构造方法去构造的;

ThreadPoolExecutor(int,int,long,TimeUnit,BlockingQueue<Runnable>);
ThreadPoolExecutor(int,int,long,TimeUnit,BlockingQueue<Runnable>,ThreadFactory);
ThreadPoolExecutor(int,int,long,TimeUnit,BlockingQueue<Runnable>,RejectedExecutionHandler);
ThreadPoolExecutor(int,int,long,TimeUnit,BlockingQueue<Runnable>
						,ThreadFactory,RejectedExecutionHandler);
						
/*
*五个参数的构造方法
*/	
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }
    
    拿第一个举例,看到其实是调用了七个参数的构造方法,使用默认的ThreadFactory和拒绝策略。

参数含义:

参数使用
corePoolSize留在池中的线程数,即使它们是空闲的,除非{@code allowCoreThreadTimeOut}设置这个参数是否生效取决于allowCoreThreadTimeOut变量的值,该变量默认是false,即对于核心线程没有超时限制,所以这种情况下,corePoolSize参数是起效的。
如果allowCoreThreadTimeOut为true,那么核心线程允许超时,并且超时时间就是keepAliveTime参数和unit共同决定的值,这种情况下,如果线程池长时间空闲的话最终存活的线程会变为0,也即corePoolSize参数失效。
maximumPoolSize池中允许的最大线程数线程池中最大的存活线程数。这个参数比较好理解,对于超出corePoolSize部分的线程,无论allowCoreThreadTimeOut变量的值是true还是false,都会超时,超时时间由keepAliveTime和unit两个参数算出。
keepAliveTime当线程数大于核心数时,这是多余的空闲线程在终止之前等待新任务的最大时间。超时时间。
unit{@code keepAliveTime}参数的时间单位超时时间的单位(TimeUnit类中有7种静态属性),天,小时,分,秒,毫秒,微秒,纳秒等,与keepAliveTime参数共同决定超时时间。
workQueue用于在任务执行之前保存它们的队列。这个队列将只保存由{@code execute}方法提交的{@code Runnable}任务。当调用execute方法时,如果线程池中没有空闲的可用线程,那么就会把这个Runnable对象放到该队列中。这个参数必须是一个实现BlockingQueue接口的阻塞队列,因为要保证线程安全。
有一个要注意的点是,只有调用execute方法,才会向这个队列中添加任务,submit方法提交任务时,如果没有可用的线程也不会直接扔掉,AbstractExecutorService类中对submit方法的实现,submit方法只是把传进来的Runnable对象或Callable对象包装成一个新的Runnable对象,然后调用execute方法,并将包装后的FutureTask对象作为一个Future引用返回给调用者。Future的阻塞特性实际是在FutureTask中实现的。
threadFactory执行程序创建新线程时要使用的工厂线程工厂类。用于在需要的时候生成新的线程。默认实现是Executors.defaultThreadFactory(),即new 一个Thread对象,并设置线程名称,daemon等属性。
handler当执行因达到线程边界和队列容量而阻塞时要使用的处理程序表示当拒绝处理任务时的策略,有以下四种取值:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

③比较重要的几个方法

方法参数/返回值
execute()Runnable command / void在Executor接口中声明,
ThreadPoolExecutor中实现,
是ThreadPoolExecutor的核心方法,
通过这个方法可以提交一个任务给线程池,由线程池去执行。
submit()Runnable task / Future<?>
Runnable task, T result / Future
Callable task / Future
在ExecutorService中声明,在AbstractExecutorService中实现,通过这个方法可以提交一个任务给线程池,但是和execute()有区别,可以通过Future类型拿到返回值。
shutdown()void / void启动一个有序的关闭,先前提交的任务将被执行,但不接受新的任务。如果已经关闭,则调用没有额外效果。
shutdownNow()void / List尝试停止所有正在执行的任务,停止正在等待的任务的处理,并返回正在等待执行的任务的列表。当从这个方法返回时,这些任务将从任务队列中被排干(删除)。

未完待续。。