Executor 框架测试用例

Executor 是JDK5新增的对于线程调度的新框架,主要用途是用来对线程进行调度和管理,

如下是Excutor框架的整体UML关系图;

本文将基于以上图片进行线程池测试用例;

1class FetchPicket implements Callable<Integer> { 2 3 @Override 4 public Integer call() throws Exception { 5 6 System.out.println("当前线程名字为:" + Thread.currentThread().getName() + " ~~~"); 7 System.out.println("开始时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); 8 Thread.sleep(10000); 9 System.out.println("结束时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); 10 return new Random().nextInt(); 11 } 12 13 }
  • newCachedThreadPool

newCachedThreadPool 方法的java doc如下:

如果没有空闲线程,按照需要创建新的线程,不过当有空闲线程时,会复用已经创建好的线程.

优点:

1,可以提高编程性能,尤其对那些寿命短,异步的任务.

注意对于超过60s未使用的线程,将会从线程池中移除.

代码如下:           

1 @Test 2 public void newCachedThreadPool() { 3 4 ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); 5 for (int i = 0; i < LOOP; i++) { 6 // 使用lambada表达式 7 Future<Integer> submit = newCachedThreadPool.submit(new FetchPicket()); 8 try { 9 if (submit.get() > 0) { 10 System.out.println("callable 的返回值是:" + submit.get()); 11 } 12 } catch (InterruptedException | ExecutionException e) { 13 14 e.printStackTrace(); 15 } 16 17 } 18 newCachedThreadPool.shutdown(); 19 }

console打印如下:

1当前线程名字为:pool-1-thread-1 ~~~ 2开始时间:2017-03-29 14:47:40 3结束时间:2017-03-29 14:47:50 4callable 的返回值是:1172363209 5当前线程名字为:pool-1-thread-1 ~~~ 6开始时间:2017-03-29 14:47:50 7结束时间:2017-03-29 14:48:00 8当前线程名字为:pool-1-thread-1 ~~~ 9开始时间:2017-03-29 14:48:00 10结束时间:2017-03-29 14:48:10 11callable 的返回值是:822004726 12当前线程名字为:pool-1-thread-2 ~~~ 13开始时间:2017-03-29 14:48:10 14结束时间:2017-03-29 14:48:20 15callable 的返回值是:547995146 16当前线程名字为:pool-1-thread-2 ~~~ 17开始时间:2017-03-29 14:48:20 18结束时间:2017-03-29 14:48:30
  • newFixedThreadPool

Java doc如下:

创建一个固定数目可重复利用的线程池,表现出一个共享无序的队列.如果线程池里所有的线程都是active,若在提交新的线程,这个线程将会被加到一个堵塞队列中直到有可用的线程.

1 @Test 2 public void newFixedThreadPool() throws InterruptedException, ExecutionException { 3 4 ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(SIZE); 5 for (int i = 0; i < LOOP; i++) { 6 Future<Integer> submit = newFixedThreadPool.submit(new FetchPicket()); 7 try { 8 if (submit.get() > 0) { 9 System.out.println("callable 的返回值是:" + submit.get()); 10 } 11 } catch (InterruptedException | ExecutionException e) { 12 13 e.printStackTrace(); 14 } 15 } 16 newFixedThreadPool.shutdown(); 17 }

console打印如下:

1当前线程名字为:pool-1-thread-1 ~~~ 2开始时间:2017-03-29 15:12:19 3结束时间:2017-03-29 15:12:29 4当前线程名字为:pool-1-thread-2 ~~~ 5开始时间:2017-03-29 15:12:29 6结束时间:2017-03-29 15:12:39 7callable 的返回值是:360730033 8当前线程名字为:pool-1-thread-1 ~~~ 9开始时间:2017-03-29 15:12:39 10结束时间:2017-03-29 15:12:49 11callable 的返回值是:1306633973 12当前线程名字为:pool-1-thread-2 ~~~ 13开始时间:2017-03-29 15:12:49 14结束时间:2017-03-29 15:12:59 15当前线程名字为:pool-1-thread-1 ~~~ 16开始时间:2017-03-29 15:12:59 17结束时间:2017-03-29 15:13:09 18callable 的返回值是:1154663265

newFixedThreadPool 和 newCachedThreadPool  区别?

1,newFixedThreadPool 的线程是不可复用的,而newCachedThreadPool  线程是可复用的.

2,newFixedThreadPool 将会保持线程池内的线程active除非出现异常,而newCachedThreadPool 只会保持默认时间60s,因此,newFixedThreadPool 会不断的创建线程,有可能导致oom.

3,对于任务时间短异步任务,建议使用newCachedThreadPool,而执行任务时间比较长的建议使用newFixedThreadPool

英文翻译如下:

  • newScheduledThreadPool

Java doc如下:

创建一个再给定的延迟时间按日期安排进行的线程池,

代码如下:

1@Test 2 public void newScheduledThreadPool() { 3 ExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(SIZE); 4 5 for (int i = 0; i < LOOP; i++) { 6 Future<Integer> submit = newScheduledThreadPool.submit(new FetchPicket()); 7 try { 8 if (submit.get() > 0) { 9 System.out.println("callable 的返回值是:" + submit.get()); 10 } 11 } catch (InterruptedException | ExecutionException e) { 12 13 e.printStackTrace(); 14 } 15 16 } 17 newScheduledThreadPool.shutdown(); 18 }

console打印如下:

1当前线程名字为:pool-1-thread-1 ~~~ 2开始时间:2017-03-29 15:36:03 3结束时间:2017-03-29 15:36:13 4callable 的返回值是:797384947 5当前线程名字为:pool-1-thread-1 ~~~ 6开始时间:2017-03-29 15:36:13 7结束时间:2017-03-29 15:36:23 8当前线程名字为:pool-1-thread-2 ~~~ 9开始时间:2017-03-29 15:36:23 10结束时间:2017-03-29 15:36:33 11当前线程名字为:pool-1-thread-1 ~~~ 12开始时间:2017-03-29 15:36:33 13结束时间:2017-03-29 15:36:43 14callable 的返回值是:1928166459 15当前线程名字为:pool-1-thread-2 ~~~ 16开始时间:2017-03-29 15:36:43 17结束时间:2017-03-29 15:36:53

分析日志可以看出,哪个线程处于空闲状态,谁抢到资源,将会执行哪个线程.

  • newSingleThreadScheduledExecutor

java doc如下

创建一个按照计划执行指令的单线程,如果该线程因为某些原因关闭,新的线程将会创建并替代他的位置.

1 @Test 2 public void newSingleThreadScheduledExecutor() { 3 ExecutorService newScheduledThreadPool = Executors.newSingleThreadScheduledExecutor(); 4 for (int i = 0; i < LOOP; i++) { 5 Future<Integer> submit = newScheduledThreadPool.submit(new FetchPicket() ); 6 try { 7 if (submit.get() > 0) { 8 System.out.println("callable 的返回值是:" + submit.get()); 9 } 10 } catch (InterruptedException | ExecutionException e) { 11 12 e.printStackTrace(); 13 } 14 15 } 16 newScheduledThreadPool.shutdown(); 17 }

console日志如下:

1当前线程名字为:pool-1-thread-1 ~~~ 2开始时间:2017-03-29 15:46:40 3结束时间:2017-03-29 15:46:50 4callable 的返回值是:387305211 5当前线程名字为:pool-1-thread-1 ~~~ 6开始时间:2017-03-29 15:46:50 7结束时间:2017-03-29 15:47:00 8callable 的返回值是:1772792044 9当前线程名字为:pool-1-thread-1 ~~~ 10开始时间:2017-03-29 15:47:00 11结束时间:2017-03-29 15:47:10 12callable 的返回值是:1354567240 13当前线程名字为:pool-1-thread-1 ~~~ 14开始时间:2017-03-29 15:47:10 15结束时间:2017-03-29 15:47:20 16当前线程名字为:pool-1-thread-1 ~~~ 17开始时间:2017-03-29 15:47:20 18结束时间:2017-03-29 15:47:30 19callable 的返回值是:1825312382

分析日志可以看出,只有一个线程在打印日志. 

  • newSingleThreadExecutor

代码如下:

1 @Test 2 public void newSingleThreadExecutor() { 3 4 5 ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor(); 6 7 for (int i = 0; i < LOOP; i++) { 8 Future<Integer> submit = newSingleThreadExecutor.submit(new FetchPicket()); 9 try { 10 if (submit.get() > 0) { 11 System.out.println("callable 的返回值是:" + submit.get()); 12 } 13 } catch (InterruptedException | ExecutionException e) { 14 15 e.printStackTrace(); 16 } 17 18 } 19 newSingleThreadExecutor.shutdown(); 20 }

console打印如下:

1当前线程名字为:pool-1-thread-1 ~~~ 2开始时间:2017-03-29 15:51:33 3结束时间:2017-03-29 15:51:43 4callable 的返回值是:1323389732 5当前线程名字为:pool-1-thread-1 ~~~ 6开始时间:2017-03-29 15:51:43 7结束时间:2017-03-29 15:51:53 8callable 的返回值是:1419085557 9当前线程名字为:pool-1-thread-1 ~~~ 10开始时间:2017-03-29 15:51:53 11结束时间:2017-03-29 15:52:03 12callable 的返回值是:423848033 13当前线程名字为:pool-1-thread-1 ~~~ 14开始时间:2017-03-29 15:52:03 15结束时间:2017-03-29 15:52:13 16callable 的返回值是:1320865693 17当前线程名字为:pool-1-thread-1 ~~~ 18开始时间:2017-03-29 15:52:13 19结束时间:2017-03-29 15:52:23

分析日志,只有一个线程在执行任务.

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Java多线程编程

  在计算机中,线程是稀缺资源,创建过多的线程,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配、调优和监控,有以下好处:降低资源消耗;提高响应速度;提高线程的可管理性。  Java多线程编程常用到多线程框架Executor,使用此框架可以方便、高效的对线程进行管理,我们先了解下Executor