java线程池Executor,ExecutorService,ThreadPoolExecutor的使用

来源:互联网 发布:java高并发解决方案 编辑:程序博客网 时间:2024/05/22 00:55

引用:

http://blog.csdn.net/evankaka/article/details/51489322


一、概述

 

1、主线程的执行与线程池里的线程互不影响,有可能主线程结束了,但是线程池里的线程还在运行

 

2、放入线程池的线程并不一定会按其放入的先后而顺序执行

 

3:线程池关系图


 

二、ExecutorsAPI介绍

Java类库提供了许多Executors静态方法来创建一个线程池


a、newFixedThreadPool 

创建一个固定长度的线程池.

fixed池中的线程不会过期(idle0)


b、newCachedThreadPool 

创建一个可缓存的线程池.

如果当前线程池的规模超出了处理需求,将回收空的线程;

当需求增加时,会增加线程数量;线程池规模无限制

reuse的线程,必须是idle(空闲) timeout内的池中线程,缺省timeout60s,超过这个idle时长,线程实例将被终止及移出线程池。


c、newSingleThreadExecutor 

创建一个单线程的Executor.

任意时间池中只能有一个线程,线程不会过期(idle0)

作用:保证线程的执行顺序,用一个线程按顺序执行等待队列中的多个任务


d、newScheduledThreadPool

建一个固定长度的线程池,而且以延迟或者定时的方式来执行,类似Timer


  • scheduleAtFixedRate()方法:按指定频率周期执行某个任务

public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);

command:执行线程 initialDelay:初始化延时  period:两次开始执行最小间隔时间 unit:计时单位

间隔指的是连续两次任务开始执行的间隔。对于scheduleAtFixedRate方法,当执行任务的时间大于我们指定的间隔时间时,它并不会在指定间隔时开辟一个新的线程并发执行这个任务。而是等待该线程执行完毕。


  • scheduleWithFixedDelay()方法:按指定频率间隔执行某个任务

public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);

command:执行线程 initialDelay:初始化延时 period:前一次执行结束到下一次执行开始的间隔时间(间隔执行延迟时间)unit:计时单位


  • scheduleAtFixedRate和scheduleWithFixedDelay对比

两者都是一个任务只会开启一个线程,上一个任务结束前下一个任务不会开始(不管线程池设的多大)

区别是FixedRate指定两次任务的开启时间间隔,FixedDelay指定两次任务的执行时间间隔

三、线程池一些常用方法


submit

Submitexecuie都可以将线程放到线程池中.区别是,submit用于执行需要返回值的子任务(Callable任务).


execute

表示往线程池添加线程,有可能会立即运行,也有可能不会。无法预知线程何时开始,何时线束。


shutdown

如果调用这个方法,一方面,表明当前线程池已不再接收新添加的线程,新添加的线程会被拒绝执行。另一方面,表明当所有线程执行完毕时,回收线程池的资源。shutdown()不会马上关闭线程池!


shutdownNow

不管当前有没有线程在执行,马上关闭线程池!这个方法要小心使用,要不可能会引起系统数据异常!


 

四、任务拒绝策略

 

① ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。  


② ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。  


③ ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)  


④ ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

 

 

五、总结

       

ThreadPoolExecutor中,包含了一个任务缓存队列和若干个执行线程,任务缓存队列是一个大小固定的缓冲区队列,用来缓存待执行的任务,执行线程用来处理待执行的任务。每个待执行的任务,都必须实现Runnable接口,执行线程调用其run()方法,完成相应任务。

ThreadPoolExecutor对象初始化时,不创建任何执行线程,当有新任务进来时,才会创建执行线程。

构造ThreadPoolExecutor对象时,需要配置该对象的核心线程池大小和最大线程池大小:

当目前执行线程的总数小于核心线程大小时,所有新加入的任务,都在新线程中处理

当目前执行线程的总数大于或等于核心线程时,所有新加入的任务,都放入任务缓存队列中

当目前执行线程的总数大于或等于核心线程,并且缓存队列已满,同时此时线程总数小于线程池的最大大小,那么创建新线程,加入线程池中,协助处理新的任务。

当所有线程都在执行,线程池大小已经达到上限,并且缓存队列已满时,就rejectHandler拒绝新的任务

 

阅读全文
0 0
原创粉丝点击