线程池在启动时即建立了大量的空闲的线程,能够指定线程的数量,但一个Runnable对象传给线程池是,线程池就会启动一个线程来执行它们的run()方法。当run()方法执行完毕时,该线程并不会死亡,而是再次返回线程池中成为空闲状态。等待执行下一个Runnable对象的run()方法java
线程池能够设置最大的并发线程数。缓存
执行一个异步任务若是是new Thread:服务器
new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }).start();
这样会有以下的弊端:网络
a.每次new Thread 新建对象的性能差多线程
b. 线程缺少统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源致使死机并发
c.缺少更多功能,如定时执行,按期执行、线程中断异步
相比new Thread ,java 提供的四种线程池的好处在于:ide
a.重用存在的线程,减小对象的建立、消亡的开销,性能佳,减小CPU在建立、消除的开销。性能
好比:spa
假设在一台服务器完成一项任务的时间为T
T1 建立线程的时间
T2 在线程中执行任务的时间,包括线程间同步所需时间
T3 线程销毁的时间
显然T = T1+T2+T3。注意这是一个极度简化的假设。
能够看出T1,T3是多线程自己的带来的开销,咱们渴望减小T1,T3所用的时间,从而减小T的时间。但一些线程的使用者并无注意到这一点,因此在程序中频繁的建立或销毁线程,这致使T1和T3在T中占有至关比例。显然这是突出了线程的弱点(T1,T3),而不是优势(并发性)。
b.可有效控制最大并发线程数,提升系统资源的使用率,同时避免过多资源竞争,避免阻塞
c.提供定时执行、按期执行、单线程、并发数控制等功能。
在Android中当同时并发多个网络线程时,引入线程池技术会极大地提升APP的性能
java 中有内置线程池 有两种线程池对象 ExecutorService----表示尽快执行线程的线程池(只要线程池中有空闲线程,就当即执行线程任务)、ScheduledExecutorService(scheduled 表示能够延迟后执行,是ExecutorService的子类)
newCachedThreadPool建立一个可缓存线程池,若是线程池长度超过处理须要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 建立一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 建立一个定长线程池,支持定时及周期性任务执行。参数表示保存的线程数,即便线程是空闲的也被保存在线程池中。
newSingleThreadExecutor 建立一个单线程化的线程池,它只会用惟一的工做线程来执行任务,保证全部任务按照指定顺序(FIFO, LIFO, 优先级)执行。
使用线程池
JDK自身带有线程池的实现类ThreadPoolExecutor
ExecutorService 提供了三个方法
一、Future<?> submit(Runnable task) 将一个Runnable 对象提交给指定的线程池,线程池将在有空闲线程是执行Runnable对象表明的任务,其中Future对象表明Runnable任务的返回值--可是run()方法执行结束后返回Null ,但能够调用Future的isDone()、isCancelled()方法来得到Runnable对象的执行状态。
二、<T>Future<T> submit(Runnable task,T result) 将一个Runnable 对象提交给指定的线程池,线程池将在有空闲线程是执行Runnable对象表明的任务,其中Future对象表明Runnable任务的返回值--能够指定显示的返回值,result为线程执行结束后的返回值。
ScheduledExecutorService 表明可在指定延迟后或周期性地执行线程任务的线程池。
一、ScheduledFuture<V> schedule(Runnable command ,long delay,TimeUnit unit)
指定command 任务将在delay延迟后执行。
二、ScheduledFuture<V> scheduleAtFixedRate(Runnable command ,long delay,long period,TimeUnit unit) 指定command 任务将在delay延迟后执行。并设置频率重复执行,也就是在delay+period、delay+2*period.........(重复执行)
用完一个线程池后,应该调用该线程池的shutdown()方法,该方法将启动线程池的关闭序列,调用该方法后的线程池再也不接收新任务,但会将之前全部已提交任务执行完毕。但线程池中的全部任务都执行完成后,池中的全部线程都会死亡。