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

引用:

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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java线程池ThreadPoolExecutorJava提供的一个用于管理和复用线程的工具类。它可以帮助我们更有效地管理线程资源,提高程序的性能和可维护性。 下面是一个简单的使用ThreadPoolExecutor的示例代码: ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolExample { public static void main(String[] args) { // 创建一个线程池,其中包含5个线程 ExecutorService executor = Executors.newFixedThreadPool(5); // 提交任务给线程池执行 for (int i = 0; i < 10; i++) { Runnable worker = new WorkerThread("Task " + i); executor.execute(worker); } // 关闭线程池 executor.shutdown(); while (!executor.isTerminated()) { // 等待所有任务完成 } System.out.println("所有任务已完成"); } } class WorkerThread implements Runnable { private String taskName; public WorkerThread(String taskName) { this.taskName = taskName; } @Override public void run() { System.out.println(Thread.currentThread().getName() + " 开始执行任务:" + taskName); try { // 模拟任务执行时间 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 完成任务:" + taskName); } } ``` 上述代码中,首先通过`Executors.newFixedThreadPool(5)`创建了一个包含5个线程的线程池。然后使用`executor.execute(worker)`提交任务给线程池执行,其中`worker`是实现了`Runnable`接口的任务对象。任务会被线程池中的线程异步执行。 最后,通过`executor.shutdown()`关闭线程池,并使用`executor.isTerminated()`等待所有任务完成。完成后输出"所有任务已完成"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值