多线程并发处理起来通常比较麻烦,如果你使用spring容器来管理业务bean,事情就好办了多了。spring封装了java的多线程的实现,你只需要关注于并发事物的流程以及一些并发负载量等特性,具体来说如何使用spring来处理并发事务:
1.了解 TaskExecutor接口
Spring的 TaskExecutor接口等同于java.util.concurrent.Executor接口。 实际上,它存在的主要原因是为了在使用线程池的时候,将对Java 5的依赖抽象出来。 这个接口只有一个方法execute(Runnable task),它根据线程池的语义和配置,来接受一个执行任务。最初创建TaskExecutor是为了在需要时给其他Spring组件提供一个线程池的抽 象。 例如ApplicationEventMulticaster组件、JMS的 AbstractMessageListenerContainer和对Quartz的整合都使用了TaskExecutor抽象来提供线程池。 当然,如果你的bean需要线程池行为,你也可以使用这个抽象层。
2. TaskExecutor接口的实现类
(1)SimpleAsyncTaskExecutor 类
这个实现不重用任何线程,或者说它每次调用都启动一个新线程。但是,它还是支持对并发总数设限,当超过线程并发总数限制时,阻塞新的调用,直到有位置被释放。如果你需要真正的池,请继续往下看。
(2)SyncTaskExecutor类
这个实现不会异步执行。相反,每次调用都在发起调用的线程中执行。它的主要用处是在不需要多线程的时候,比如简单的test case。
(3)ConcurrentTaskExecutor 类
这个实现是对 Java 5 java.util.concurrent.Executor类的包装。有另一个备选, ThreadPoolTaskExecutor类,它暴露了Executor的配置参数作为bean属性。很少需要使用 ConcurrentTaskExecutor, 但是如果ThreadPoolTaskExecutor不敷所需,ConcurrentTaskExecutor是另外一个备选。
(4)SimpleThreadPoolTaskExecutor 类
这个实现实际上是Quartz的SimpleThreadPool类的子类,它会监听Spring的生命周期回调。当你有线程池,需要在Quartz和非Quartz组件中共用时,这是它的典型用处。
(5)ThreadPoolTaskExecutor 类
它不支持任何对 java.util.concurrent包的替换或者下行移植。Doug Lea和Dawid Kurzyniec对java.util.concurrent的实现都采用了不同的包结构,导致它们无法正确运行。 这个实现只能在Java 5环境中使用,但是却是这个环境中最常用的。它暴露的bean properties可以用来配置一个java.util.concurrent.ThreadPoolExecutor,把它包装到一个 TaskExecutor中。如果你需要更加先进的类,比如ScheduledThreadPoolExecutor,我们建议你使用 ConcurrentTaskExecutor来替代。
(6)TimerTaskExecutor类
这个实现使用一个TimerTask作为其背后的实现。它和SyncTaskExecutor的不同在于,方法调用是在一个独立的线程中进行的,虽然在那个线程中是同步的。
(7)WorkManagerTaskExecutor类
这个实现使用了 CommonJ WorkManager作为其底层实现,是在Spring context中配置CommonJ WorkManager应用的最重要的类。和SimpleThreadPoolTaskExecutor类似,这个类实现了WorkManager接口, 因此可以直接作为WorkManager使用。
3.线程池Demo之 ThreadPoolTaskExecutor
(1)编写测试类
01 |
import org.springframework.core.task.TaskExecutor; |
03 |
public class MainExecutor { |
04 |
private TaskExecutor taskExecutor;
|
05 |
public MainExecutor (TaskExecutor taskExecutor) {
|
06 |
this.taskExecutor = taskExecutor;
|
08 |
public void printMessages() {
|
09 |
for(int i = 0; i < 25; i++) {
|
10 |
taskExecutor.execute(new MessagePrinterTask("Message" + i));
|
15 |
private class MessagePrinterTask implements Runnable {
|
16 |
private String message;
|
17 |
public MessagePrinterTask(String message) {
|
18 |
this.message = message;
|
21 |
System.out.println(message);
|
在业务代码中,通常以for循环的方式执行多个事务
for(int k = 0; k < n; k++) {
taskExecutor.execute(new ThreadTransCode());
}
其它繁琐的线程管理的事情就交给执行器去管理。
值得注意的事有两点
1, taskExecutor.execute(new ThreadTransCode()); 激活的线程都是守护线程,主线程结束,守护线程就会放弃执行,这个在业务中式符合逻辑的,在单元测试中为了看到执行效果,需要自行阻塞主线程。
2, taskExecutor.execute(new ThreadTransCode()); 的执行也不是完全安全的,在执行的过程中可能会因为需要的线程查过了线程队列的容量而抛出运行时异常,如有必要需要捕获。
(2)spring的配置
01 |
<? xml version = "1.0" encoding = "UTF-8" ?>
|
02 |
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "/spring-beans.dtd"> |
06 |
< bean id = "threadPool" class = "org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
|
08 |
< property name = "corePoolSize" value = "10" />
|
10 |
< property name = "maxPoolSize" value = "50" />
|
12 |
< property name = "queueCapacity" value = "1000" />
|
14 |
< property name = "keepAliveSeconds" value = "300" />
|
16 |
< property name = "rejectedExecutionHandler" >
|
17 |
< bean class = "java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
|
21 |
< bean id = "mainExecutor" class = "supben.MainExecutor" >
|
22 |
< property name = "threadPool" ref = "threadPool" />
|
25 |
< bean id = "springScheduleExecutorTask" class = "org.springframework.scheduling.concurrent.ScheduledExecutorTask" >
|
26 |
< property name = "runnable" ref = "mainExecutor" />
|
28 |
< property name = "delay" value = "10000" />
|
30 |
< property name = "period" value = "5000" />
|
33 |
< bean id = "springScheduledExecutorFactoryBean" class = "org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean" >
|
34 |
< property name = "scheduledExecutorTasks" >
|
36 |
< ref bean = "springScheduleExecutorTask" />
|
(3)调用
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
MainExecutor te = (MainExecutor)appContext.getBean("taskExecutorExample");
te.printMessages();
System.out.println("11111111111111111111111");
(4)效果
相关推荐
数据库连接是一种关键的有限的昂贵的资源,这一点在多用户网页应用程序中体现的尤为突出。对数据库连接的管理能显著影响到整个应用的伸缩性和健壮性,影响到程序的性能指标。
Spring Boot中内置了多种线程池,为应用程序提供快速响应和高吞吐量的运行环境。线程池在Spring Boot中起着至关重要的作用,它能够有效地管理和复用线程,降低系统的开销。本文将详细介绍线程池的基本参数、每一种...
主要给大家介绍了关于Spring Boot利用@Async如何实现异步调用:自定义线程池的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...
6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...
6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. ...
主要介绍了spring boot 监控处理方案的相关资料,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. ...
6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...
是一个轻量级线程池管理系统,能够集中管理不同应用、不同集群的线程配置,修改配置后能够实时刷新,使用起来,简单易用。 支持JAVA客户端,可在Spring/Spring Boot环境下运行 支持JKD1.8,以及更高版本。 演示 : ...
虽然可以通过属性文件(在属性文件中可以指定 JDBC 事务的数据源、全局作业和/或触发器侦听器、插件、线程池,以及更多)配置 Quartz,但它根本没有与应用程序服务器的上下文或引用集成在一起。结果就是作业不能访问...
+ 熔断机制 + eureka + 单元测试(controller、service、mapper层) + redis集群集成练习 + redis操作练习 + fastDFS集成练习 + 全局拦截器 + 定时器配置 + 定时器任务设计[线程池+分布式锁] +关闭挂钩 + 单例应用 + ...
虽然可以通过属性文件(在属性文件中可以指定 JDBC 事务的数据源、全局作业和/或触发器侦听器、插件、线程池,以及更多)配置 Quartz,但它根本没有与应用程序服务器的上下文或引用集成在一起。结果就是作业不能访问...
在传统Spring应用中使用spring-boot-actuator模块提供监控端点 Spring Boot应用的后台运行配置 Spring Boot自定义Banner Dubbo进行服务治理 chapter9-2-1:Spring Boot中使用Dubbo进行服务治理 chapter9-2-2:Spring...
Spring还提供了这些接口的实现,这些接口支持线程池或将其委托给应用服务器环境中的CommonJ。 Spring2.0开始引入的新的抽像。Executors是线程池的Java5名称。之所以称作是“执行器”是因为不能保证底层实现实际上是...
SpringCloud:基于Spring Boot实现的云原生应用开发工具,SpringCloud使用的技术:(Spring Cloud Gateway、Spring Cloud Alibaba Nacos、Spring Cloud Alibaba Sentinel、Spring Cloud Task和Spring Cloud Feign等...
主要给大家介绍了关于Spring Boot如何优雅的使用多线程的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
应用服务器jetty, 内嵌在Spring-Boot里. 准备测试一下几种matrix 方式 HTTP线程池 工作线程池 工作线程等待时间 异步 16 16 1s 异步 16 16 0.1s 同步 16 16 1s 同步 16 16 0.1s 同步 100 16 1s 同步 200 16 1s 并发...
src\main\resources\sql:内含 可用sql文件 springboot项目,集成maven依赖:参见pom.xml,如: lombok、log4j2、validation、hutool、commons-lang3、fastjson、poi、knife4j依赖swagger、mysql ...12、线程池应用。
本工程包含了SpringAOP,死锁,JUC同步锁,读-写同步锁,线程本地使用,JUC线程池和Spring提供的线程池,jdk 1.8中的日期时间API,数据结构中图的实现及操作和广度优先遍历/深度优先遍历(其他待完善),生成XML文件...