springboot中使用

@Configuration
@EnableAsync
public class Test02 {
@Bean("taskModuleExecutor")
ThreadPoolTaskExecutor getCrawler1(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(3);
threadPoolTaskExecutor.setMaxPoolSize(10);
threadPoolTaskExecutor.setQueueCapacity(200);
threadPoolTaskExecutor.setThreadNamePrefix("task-concurrent-work");
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
} }
   @Resource(name="taskModuleExecutor")
private TaskExecutor taskExecutor;

一般实际开发中经常用到多线程,所以需要使用线程池了,

 ThreadPoolTaskExecutor通常通过XML方式配置,或者通过Executors的工厂方法进行配置。 
 XML方式配置代码如下:交给spring来管理;

  <bean id="taskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 核心线程数 -->
<property name="corePoolSize" value="4000" />
<!-- 最大线程数 -->
<property name="maxPoolSize" value="20000" />
<!-- 队列最大长度 -->
<property name="queueCapacity" value="2000" />
<!-- 线程池维护线程所允许的空闲时间 -->
<property name="keepAliveSeconds" value="30" />
<!-- 线程池对拒绝任务(无线程可用)的处理策略 -->
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$DiscardPolicy" />
</property>
</bean>

rejectedExecutionHandler字段用于配置拒绝策略,常用的拒绝策略如下:

AbortPolicy,用于被拒绝任务的处理程序,它将抛出RejectedExecutionException。

CallerRunsPolicy,用于被拒绝任务的处理程序,它直接在execute方法的调用线程中运行被拒绝的任务。

DiscardOldestPolicy,用于被拒绝任务的处理程序,它放弃最旧的未处理请求,然后重试execute

DiscardPolicy,用于被拒绝任务的处理程序,默认情况下它将丢弃被拒绝的任务。


提交任务

无返回值的任务使用execute(Runnable)

有返回值的任务使用submit(Runnable)


案例代码

 threadPoolTaskExecutor.execute(new Runnable() {
public void run() {
synchronized (Controller01.class) {
try {
HttpUtils.get("http://192.168.31.223:8085/test2.do");
System.out.println(System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
}
}
} });

任务处理流程:

  • 当一个任务被提交到线程池时,首先查看线程池的核心线程是否都在执行任务,否就选择一条线程执行任务,是就执行第二步。
  • 查看核心线程池是否已满,不满就创建一条线程执行任务,否则执行第三步。
  • 查看任务队列是否已满,不满就将任务存储在任务队列中,否则执行第四步。
  • 查看线程池是否已满,不满就创建一条线程执行任务,否则就按照策略处理无法执行的任务。

在ThreadPoolExecutor中表现为:

  • 如果当前运行的线程数小于corePoolSize,那么就创建线程来执行任务(执行时需要获取全局锁)。
  • 如果运行的线程大于或等于corePoolSize,那么就把task加入BlockQueue。
  • 如果创建的线程数量大于BlockQueue的最大容量,那么创建新线程来执行该任务。
  • 如果创建线程导致当前运行的线程数超过maximumPoolSize,就根据饱和策略来拒绝该任务。

关闭线程池

调用shutdown或者shutdownNow,

两者都不会接受新的任务,而且通过调用要停止线程的interrupt方法来中断线程,有可能线程永远不会被中断,

不同之处在于shutdownNow会首先将线程池的状态设置为STOP,然后尝试停止所有线程(有可能导致部分任务没有执行完)然后返回未执行任务的列表。

而shutdown则只是将线程池的状态设置为shutdown,然后中断所有没有执行

任务的线程,并将剩余的任务执行完。


常用状态:

  • taskCount:线程需要执行的任务个数。
  • completedTaskCount:线程池在运行过程中已完成的任务数。
  • largestPoolSize:线程池曾经创建过的最大线程数量。
  • getPoolSize获取当前线程池的线程数量。
  • getActiveCount:获取活动的线程的数量

通过继承线程池,重写beforeExecuteafterExecuteterminated方法来在线程执行任务前,线程执行任务结束,和线程终结前获取线程的运行情况,根据具体情况调整线程池的线程数量


使用场景

1、当你的任务是非必要的时候。比如记录操作日志、通知第三方服务非必要信息等,可以使用线程池处理非阻塞任务 
      2、当你的任务非常耗时时候,可以采用线程池技术 
      3、当请求并发很高时,可以采用线程池技术优化处理


多线程是不是能加快处理速度?

在使用多线程时,一定要知道一个道理:处理速度的最终决定因素是CPU、内存等,在单CPU(无论多少核)上,分配CPU资源的单位是“进程”而不是“线程”。

我们可以做一个简单的试验:

假设我要拷贝100万条数据,单CPU电脑,用一个进程,在单线程的情况下,CPU占用率为5%,耗时1000秒。那么当在这个进程下,开辟10个线程同时去运行,是不是CPU占用率增加到50%,耗时减少到100秒呢?显然不是。我实测出来的情况是这样的:

“CPU占用率仍然是5%,总耗时仍然是1000秒。且每个线程的运行时间也为1000秒。”


总结:

第一,

看硬件。如果是在比较强大的、多CPU的服务器上运行程序,可以使用多线程来提高并发数和执行速度。

但是线程也不宜过多,即使是16个CPU的服务器,同一时间最多也只能真正意义上地并发处理16个线程,多出来的线程还是要等待。

第二,

看用途。如果你不在乎处理速度,仅仅是为了提高并发处理能力,那么理所当然地用多线程,

但是如果你仅仅是想提高处理速度,且又是在单CPU机器上运行,那么多线程并不值得。

如果你的任务很耗时,且可以一部分、一部分地做,那么最好不要用多线程(好比搬       砖,单线程一次搬10块,总共搬10天,但搬一块算一块,到第9天的时候,你就搬完90块砖了;

如果你用10个线程同时去搬砖,同样要搬10天,但是到第9天的时候,这10个线程100块砖都“还在路上”,一块砖都没搬完!)。

线程池ThreadPoolTaskExecutor配置说明的更多相关文章

  1. Spring的线程池ThreadPoolTaskExecutor使用案例

    1.Sping配置文件 <!-- 线程池配置 --> <bean id="threadPool" class="org.springframework. ...

  2. Spring线程池ThreadPoolTaskExecutor配置及详情

    Spring线程池ThreadPoolTaskExecutor配置及详情 1. ThreadPoolTaskExecutor配置 <!-- spring thread pool executor ...

  3. SPRING中的线程池ThreadPoolTaskExecutor(转)

    转自:https://blog.csdn.net/zhanglongfei_test/article/details/51888433 一.初始化 1,直接调用 ThreadPoolTaskExecu ...

  4. spring线程池ThreadPoolTaskExecutor与阻塞队列BlockingQueue

    一: ThreadPoolTaskExecutor是一个spring的线程池技术,查看代码可以看到这样一个字段: private ThreadPoolExecutor threadPoolExecut ...

  5. spring boot: 线程池ThreadPoolTaskExecutor, 多线程

    由于项目里需要用到线程池来提高处理速度,记录一下spring的taskExecutor执行器来实现线程池. ThreadPoolTaskExecutor的配置在网上找了很多解释没找到,看了下Threa ...

  6. Spring中的线程池ThreadPoolTaskExecutor介绍

    前言: Java SE 5.0引入了ThreadPoolExecutor.ScheduledThreadPoolExecutor.Spring 2.x借助ConcurrentTaskExecutor和 ...

  7. SPRING中的线程池ThreadPoolTaskExecutor

    一.初始化 1,直接调用 ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor(); //线程池所使用的缓冲队列 p ...

  8. 【SSM Spring 线程池 OJ】 使用Spring线程池ThreadPoolTaskExecutor

    最近做的Online Judge项目,在本地判题的实现过程中,遇到了一些问题,包括多线程,http通信等等.现在完整记录如下: OJ有一个业务是: 用户在前端敲好代码,按下提交按钮发送一个判题请求给后 ...

  9. springBoot服务整合线程池ThreadPoolTaskExecutor与@Async详解使用

    ThreadPoolExecutor:=======这个是java自己实现的线程池执行类,基本上创建线程池都是通过这个类进行的创建.ThreadPoolTaskExecutor:========这个是 ...

随机推荐

  1. Fastjson反序列化漏洞研究

    0x01 Brief Description java处理JSON数据有三个比较流行的类库,gson(google维护).jackson.以及今天的主角fastjson,fastjson是阿里巴巴一个 ...

  2. javac编译多个java文件以及-cp、-classp、-sourcepath

    //编译多个文件 javac  path_of_file_a/a.java path_of_file_b/b.java path_of_file_c/c.java   -cp(classpath) 与 ...

  3. Spring-Boot配置文件web性能(服务器)配置项

    参数 介绍server.address 服务器应绑定到的网络地址server.compression.enabled = false 如果启用响应压缩server.compression.exclud ...

  4. window C/C++ 简单的IDE编译器

    C-Free 官网链接: http://www.programarts.com/cfree_ch/download.htm

  5. ZOJ 3604 Tunnel Network(凯莱定理)

    题目链接: E - Tunnel Network ZOJ - 3604 题目大意: 给定编号1-n的点,和给定编号1-S 的联通图,刚开始1号联通图只有 1个顶点,就是编号为1的顶点,2号联通图也只有 ...

  6. 428 Setup MySQL + - 改

    初步认识MySQL 安装 练习增减改 1.什么是数据库软件: 数据库,俗称数据的仓库.方便管理数据的软件(或程序) 市面上数据库软件: Oracle:甲骨文公司产品.当前最流行应用最广泛数据库软件.和 ...

  7. re模块 - 正则表达式 疏理(一)

    在网上总是很难找到令自己比较满意的,关于正则表达式的文章.所以决定自己来总结一波,并配上相应的示例. 正则表达式:定义了规则,用来字符串处理. 用途: 1.匹配 - 符合规则的字符串,则认为匹配了. ...

  8. iOS 开发 ZFUI framework控件,使布局更简单

    来自:http://www.jianshu.com/p/bcf86b170d9c 前言 为什么会写这个?因为在iOS开发中,界面的布局一直没有Android布局有那么多的方法和优势,我个人开发都是纯代 ...

  9. PHP 【六】

    命名空间 教学网站的内容不知道再怎么“笔记化”,用之即可 面向对象 类定义 创建对象  $xxx = new 类名: 调用成员方法  $xxx->方法名(参数): 举例: <?php cl ...

  10. 【转】一文掌握 Linux 性能分析之 I/O 篇

    [转]一文掌握 Linux 性能分析之 I/O 篇 这是 Linux 性能分析系列的第三篇,前两篇分别讲了 CPU 和 内存,本篇来看 IO. IO 和 存储密切相关,存储可以概括为磁盘,内存,缓存, ...