码迷,mamicode.com
首页 > 编程语言 > 详细

线程池

时间:2018-03-11 21:12:21      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:while   排队   str   很多   lock   rmi   queue   span   val   

什么是线程池?

线程池是基于对象池的思想,开辟一块内存空间,里面存放了众多线程,池中线程的调度交给池管理器来管理

为什么要使用线程池?

在并发任务很多的情况下,每一个线程执行很短的时间就结束了,线程频繁地创建和销毁会大大减低系统的性能,我们创建一个线程池,

当任务需要执行时,线程池会分配一条线程池中的线程去处理此任务,处理完以后放回池中继续去处理其他任务,,使线程得到复用。

java中的ThreadPoolExecutor类:

ThreadPoolExecutor构造器中各个参数的含义:

corePoolSize:核心池线程数的大小,创建线程池时,默认情况下线程池中并没有线程,直到有任务到来时才去创建线程去处理任务,除非调用

preStartAllCoreThreads()和preStartCoreThread()方法(分别创建corePoolSize个线程和一个线程),当池中的线程数达到核心池的最大线程数是,

就会把放到的任务当道缓存队列中;

maximumPoolSzie:线程池中允许的最大线程数,当线程池中的线程数大于核心池线程数并且阻塞队列已满,如果此时线程池中的最大线程数还没有达到

maximumPoolSize,那么将会新创建一个线程去处理此任务。

KeepAliveTime:线程处于空闲状态的最大存活时间,默认只有在线程池中的线程数超过corePoolSize才有用,会将线程池中处于空闲状态持续超过KeepAliveTme

的线程,直到池中的线程数不大于corePoolSize,即核心池的线程数。

unit:KeepAliveTime的时间单位

workQueue:存放任务的阻塞队列,有几种参数的选择,下面会细讲。

threadFactory:线程 工厂

handler:拒绝处理任务时的策略;

ThreadPoolExecutor有几个非常重要的方法:

executor(Runnable commad):最顶层接口Executor唯一声明的方法,调用此方法向线程提交一个任务,交给线程去执行。

shutDown():将线程池的状态置为SHUTDOWN,相当于关闭线程,将不再接受新的任务,等待阻塞队列中的任务执行完毕。

shutDownNow():将线程池的状态置为STOP,线程池将不会接受新的任务,并尝试终止当前执行的任务。

线程池几种状态:

1.RUNNING

2.SHUTDOWN

3.SHUTDOWNOW

4.TERMINALS:当线程池处于stop或shutdown状态并且所有工作线程已被销毁,阻塞已经清空,线程池状态将被置为terminals;

任务的执行过程:

1.将任务提交给线程池,即调用executor(Runnable command)方法,当任务为空时抛出空指针异常。

2.判断当前线程数是否大于核心池线程数,如果大于,会将任务尝试添加到阻塞队列中,排队等待空闲的线程取出执行,如果添加失败,

会尝试创建新的线程去执行,如果当前线程池中的线程数大于maximumPoolSize,线程池会采取任务拒绝策略(丢弃任务抛出异常等)

3.当前线程数小与核心池的线程数,那么就会调用addIfUnderCoreSize(Runnable command)这个方法,这个方法会去创建工作线程去执行当前任务,

将创建工作线程的操作放在使用Lock锁的同步块中,防处理同一任务的工作线程被多次创建,在工作线程的run()方法中有 一个while循环,当前工作线程

执行完当前任务以后,会继续到阻塞队列中取出任务执行,直到取不到任务,然后根据当前线程池的状态决定当前工作线程是否退出。

4.任务缓存队列及排队策略

workQueue的类型为BlockingQueue<Runnable>,通常可以取下面三种类型:

1.直接提交策略:缓存队列使用synchronousQueue(同步队列)

ExcutorService cachedThreadPool=Executors.newCachedThreadPool(),默认线程池的最大线程数为Integer.MAX_VALUE,KeepAliveTime为60s,

提交任务时,任务不会进入队列,而是判断线程池中是否有一个空闲来处理该队列,如果有则入队,如果没有,则去创建一个线程来处理此任务,

适用于负载较轻的服务器。

2)无界策略使用LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE,默认KeepAliveTime为0,指定线程池最大允许的线程数

ExecutorService pool = Executors.newFixedThreadPool(最大允许线程数);

3)有界队列使用ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小,不提倡此种策略,当并发量大时,有可能造成资源耗尽。

 

  

 

 

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

线程池

标签:while   排队   str   很多   lock   rmi   queue   span   val   

原文地址:https://www.cnblogs.com/ChenXionghfut/p/8545304.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!