本文概览:使用spring线程池来实现多线程处理detail,并且需要每一线程会返回一个结果。

1 spring线程池与JDK线程池区别

spring线程池是通过JDK的线程池ThreadPoolExecutor的实现。但是具有如下两个优点

(1)不需要自己设置阻塞队列

只需要设置阻塞队列大小,不需要指定那种阻塞队列。

(2)自动关闭线程池

通过实现DisposableBean的destroy方法

2 实例

2.1 场景

 我们有一个场景,分批从数据库中读取1000条数据Detail,使用调用外部服务(HTTP的服务接口格式)处理这1000个数据,然后记录成功个数和失败个数。对于上述操作进行优化,我们可以通过多线程方式来实现调用外部服务来处理这个数据。

2.2 代码

1、实现要点

  • 需要获取每一个线程执行之后的结果

2、sping的xml中定义线程池

一般情况下我们都设置corePoolSzie和maxPoolSize的大小是一样的,那么此时也就不需要keepAliveSeconds了。如下:

对于线程池的大小策略为:CPU个数+1。cpu的个数查看参考:

设置线程池大小和linux 查看cpu核数

3、相关代码

(1)待处理的对象

(2)多线程处理detail抽象类

  • 定义了一个Callable(ProcessCallable)和Callable的返回类型(ProcessCallableResult)的两个类
  • 定义了一个获取线程持仓的抽象方法。

(3)多线程处理detail的具体类

实现了两个方法

  • 处理detail的方法processOneDetail
  • 获取线程池方法getThreadPool

(4)测试类

具体测试类

抽象测试类

执行结果为

14:30:27.017 [processExecutor-4] INFO concurrent.ProcessWithResult – process detail success

14:30:27.017 [processExecutor-1] INFO concurrent.ProcessWithResult – process detail success

14:30:27.017 [processExecutor-5] INFO concurrent.ProcessWithResult – process detail fail

14:30:27.017 [processExecutor-3] INFO concurrent.ProcessWithResult – process detail success

14:30:27.017 [processExecutor-2] INFO concurrent.ProcessWithResult – process detail fail

14:30:27.025 [main] INFO concurrent.ProcessWithResult – 执行失败

14:30:27.025 [main] INFO concurrent.ProcessWithResult – 程序执行完成,处理结果为:totalCount5;totalAmount=24;successCount=3;successAmount=17;failCount=2;failAmount=7

4、 github的代码地址

git@github.com:zhonghuwu/iocTemplate.git

(全文完)

分类&标签

发表评论

电子邮件地址不会被公开。 必填项已用*标注