Executor 框架测试用例

Stella981
• 阅读 639

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

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

Executor 框架测试用例

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

class FetchPicket implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {

            System.out.println("当前线程名字为:" + Thread.currentThread().getName() + " ~~~");
            System.out.println("开始时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            Thread.sleep(10000);
            System.out.println("结束时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            return new Random().nextInt();
        }

    }
  • newCachedThreadPool

newCachedThreadPool 方法的java doc如下:

Executor 框架测试用例

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

优点:

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

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

代码如下:           

    @Test
    public void newCachedThreadPool() {

        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < LOOP; i++) {
            // 使用lambada表达式
            Future<Integer> submit = newCachedThreadPool.submit(new FetchPicket());
            try {
                if (submit.get() > 0) {
                    System.out.println("callable 的返回值是:" + submit.get());
                }
            } catch (InterruptedException | ExecutionException e) {

                e.printStackTrace();
            }

        }
        newCachedThreadPool.shutdown();
    }

console打印如下:

当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 14:47:40
结束时间:2017-03-29 14:47:50
callable 的返回值是:1172363209
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 14:47:50
结束时间:2017-03-29 14:48:00
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 14:48:00
结束时间:2017-03-29 14:48:10
callable 的返回值是:822004726
当前线程名字为:pool-1-thread-2 ~~~
开始时间:2017-03-29 14:48:10
结束时间:2017-03-29 14:48:20
callable 的返回值是:547995146
当前线程名字为:pool-1-thread-2 ~~~
开始时间:2017-03-29 14:48:20
结束时间:2017-03-29 14:48:30
  • newFixedThreadPool

Java doc如下:

Executor 框架测试用例

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

    @Test
    public void newFixedThreadPool() throws InterruptedException, ExecutionException {

        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(SIZE);
        for (int i = 0; i < LOOP; i++) {
            Future<Integer> submit = newFixedThreadPool.submit(new FetchPicket());
            try {
                if (submit.get() > 0) {
                    System.out.println("callable 的返回值是:" + submit.get());
                }
            } catch (InterruptedException | ExecutionException e) {

                e.printStackTrace();
            }
        }
        newFixedThreadPool.shutdown();
    }

console打印如下:

当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:12:19
结束时间:2017-03-29 15:12:29
当前线程名字为:pool-1-thread-2 ~~~
开始时间:2017-03-29 15:12:29
结束时间:2017-03-29 15:12:39
callable 的返回值是:360730033
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:12:39
结束时间:2017-03-29 15:12:49
callable 的返回值是:1306633973
当前线程名字为:pool-1-thread-2 ~~~
开始时间:2017-03-29 15:12:49
结束时间:2017-03-29 15:12:59
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:12:59
结束时间:2017-03-29 15:13:09
callable 的返回值是:1154663265

newFixedThreadPool 和 newCachedThreadPool  区别?

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

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

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

英文翻译如下:

Executor 框架测试用例

  • newScheduledThreadPool

Java doc如下:

Executor 框架测试用例

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

代码如下:

@Test
    public void newScheduledThreadPool() {
        ExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(SIZE);

        for (int i = 0; i < LOOP; i++) {
            Future<Integer> submit = newScheduledThreadPool.submit(new FetchPicket());
            try {
                if (submit.get() > 0) {
                    System.out.println("callable 的返回值是:" + submit.get());
                }
            } catch (InterruptedException | ExecutionException e) {

                e.printStackTrace();
            }

        }
        newScheduledThreadPool.shutdown();
    }

console打印如下:

当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:36:03
结束时间:2017-03-29 15:36:13
callable 的返回值是:797384947
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:36:13
结束时间:2017-03-29 15:36:23
当前线程名字为:pool-1-thread-2 ~~~
开始时间:2017-03-29 15:36:23
结束时间:2017-03-29 15:36:33
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:36:33
结束时间:2017-03-29 15:36:43
callable 的返回值是:1928166459
当前线程名字为:pool-1-thread-2 ~~~
开始时间:2017-03-29 15:36:43
结束时间:2017-03-29 15:36:53

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

  • newSingleThreadScheduledExecutor

java doc如下

Executor 框架测试用例

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

   @Test
    public void newSingleThreadScheduledExecutor() {
        ExecutorService newScheduledThreadPool = Executors.newSingleThreadScheduledExecutor();
        for (int i = 0; i < LOOP; i++) {
            Future<Integer> submit = newScheduledThreadPool.submit(new FetchPicket() );
            try {
                if (submit.get() > 0) {
                    System.out.println("callable 的返回值是:" + submit.get());
                }
            } catch (InterruptedException | ExecutionException e) {

                e.printStackTrace();
            }

        }
        newScheduledThreadPool.shutdown();
    }

console日志如下:

当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:46:40
结束时间:2017-03-29 15:46:50
callable 的返回值是:387305211
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:46:50
结束时间:2017-03-29 15:47:00
callable 的返回值是:1772792044
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:47:00
结束时间:2017-03-29 15:47:10
callable 的返回值是:1354567240
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:47:10
结束时间:2017-03-29 15:47:20
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:47:20
结束时间:2017-03-29 15:47:30
callable 的返回值是:1825312382

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

  • newSingleThreadExecutor

Executor 框架测试用例

代码如下:

    @Test
    public void newSingleThreadExecutor() {


        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();

        for (int i = 0; i < LOOP; i++) {
            Future<Integer> submit = newSingleThreadExecutor.submit(new FetchPicket());
            try {
                if (submit.get() > 0) {
                    System.out.println("callable 的返回值是:" + submit.get());
                }
            } catch (InterruptedException | ExecutionException e) {

                e.printStackTrace();
            }

        }
        newSingleThreadExecutor.shutdown();
    }

console打印如下:

当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:51:33
结束时间:2017-03-29 15:51:43
callable 的返回值是:1323389732
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:51:43
结束时间:2017-03-29 15:51:53
callable 的返回值是:1419085557
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:51:53
结束时间:2017-03-29 15:52:03
callable 的返回值是:423848033
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:52:03
结束时间:2017-03-29 15:52:13
callable 的返回值是:1320865693
当前线程名字为:pool-1-thread-1 ~~~
开始时间:2017-03-29 15:52:13
结束时间:2017-03-29 15:52:23

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

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
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
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
1星期前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
2年前
Java多线程编程
  在计算机中,线程是稀缺资源,创建过多的线程,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配、调优和监控,有以下好处:降低资源消耗;提高响应速度;提高线程的可管理性。  Java多线程编程常用到多线程框架Executor,使用此框架可以方便、高效的对线程进行管理,我们先了解下Executor
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
2年前
Executor框架
任务是一组逻辑工作单元,而线程则是使任务异步执行的机制。线程池简化了线程的管理工作,并且java.util.concurrent提供了一种灵活的线程池实现作为Executor框架的一部分。在Java类库中,任务执行的主要抽象不是Thread,而是Executor,如下所示:publicinterfaceExecutor{void
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
2年前
Executor框架(二)Executor 与 ExecutorService两个基本接口
一、Executor接口简介Executor接口是Executor框架的一个最基本的接口,Executor框架的大部分类都直接或间接地实现了此接口。只有一个方法voidexecute(Runnablecommand):在未来某个时间执行给定的命令。该命令可能在新的线程、已入池的线程或者正调用的线程中执行,这由Execut
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
6个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这