java(Android)线程池

系统启动一个新的线程的成本是比较高的,因为它涉及到了有操作系统的交互,当程序性要创建大量生存期很短暂的线程时,更应该考虑使用线程池。

 

线程池在启动时即创建了大量的空闲的线程,可以指定线程的数量,但一个Runnable对象传给线程池是,线程池就会启动一个线程来执行它们的run()方法。当run()方法执行完毕时,该线程并不会死亡,而是再次返回线程池中成为空闲状态。等待执行下一个Runnable对象的run()方法

 

线程池可以设置最大的并发线程数。

 

 

1、new Thread 的弊端

执行一个异步任务如果是new Thread:

new Thread(new Runnable() {

	@Override
	public void run() {
		// TODO Auto-generated method stub
	}
}).start();

这样会有如下的弊端:

a.每次new Thread 新建对象的性能差

b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机

c.缺乏更多功能,如定时执行,定期执行、线程中断

 

相比new Thread ,java 提供的四种线程池的好处在于:

a.重用存在的线程,减少对象的创建、消亡的开销,性能佳,减少CPU在创建、消除的开销。

比如:

 假设在一台服务器完成一项任务的时间为T
     T1 创建线程的时间    
     T2 在线程中执行任务的时间,包括线程间同步所需时间    
     T3 线程销毁的时间     
     显然T = T1+T2+T3。注意这是一个极度简化的假设。
     可以看出T1,T3是多线程本身的带来的开销,我们渴望减少T1,T3所用的时间,从而减少T的时间。但一些线程的使用者并没有注意到这一点,所以在程序中频繁的创建或销毁线程,这导致T1和T3在T中占有相当比例。显然这是突出了线程的弱点(T1,T3),而不是优点(并发性)。

 

b.可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免阻塞

c.提供定时执行、定期执行、单线程、并发数控制等功能。

 

在Android中当同时并发多个网络线程时,引入线程池技术会极大地提高APP的性能

2、java 线程池

java 中有内置线程池 有两种线程池对象 ExecutorService----表示尽快执行线程的线程池(只要线程池中有空闲线程,就立即执行线程任务)、ScheduledExecutorService(scheduled 表示可以延迟后执行,是ExecutorService的子类)

 

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。参数表示保存的线程数,即使线程是空闲的也被保存在线程池中。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

使用线程池

JDK自身带有线程池的实现类ThreadPoolExecutor

 

ExecutorService 提供了三个方法

    1、Future<?> submit(Runnable task) 将一个Runnable 对象提交给指定的线程池,线程池将在有空闲线程是执行Runnable对象代表的任务,其中Future对象代表Runnable任务的返回值--但是run()方法执行结束后返回Null ,但可以调用Future的isDone()、isCancelled()方法来获得Runnable对象的执行状态。

    2、<T>Future<T> submit(Runnable task,T result) 将一个Runnable 对象提交给指定的线程池,线程池将在有空闲线程是执行Runnable对象代表的任务,其中Future对象代表Runnable任务的返回值--可以指定显示的返回值,result为线程执行结束后的返回值。

 

ScheduledExecutorService 代表可在指定延迟后或周期性地执行线程任务的线程池。

1、ScheduledFuture<V> schedule(Runnable command ,long delay,TimeUnit unit)

    指定command 任务将在delay延迟后执行。

2、ScheduledFuture<V> scheduleAtFixedRate(Runnable command ,long delay,long period,TimeUnit unit)   指定command 任务将在delay延迟后执行。并设置频率重复执行,也就是在delay+period、delay+2*period.........(重复执行)

 

用完一个线程池后,应该调用该线程池的shutdown()方法,该方法将启动线程池的关闭序列,调用该方法后的线程池不再接收新任务,但会将以前所有已提交任务执行完毕。但线程池中的所有任务都执行完成后,池中的所有线程都会死亡。

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。