多线程

  Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor。而实际开发中任务一般是非阻碍的,即异步的,所以我们要在配置类中通过@EnableAsync开启对异步任务的支持,并通过在实际执行的Bean的方法中使用@Async注解声明其是一个异步任务。

  此外,还提供一种Java的实现方式,多种方式去尝试如何去实现多线程。

实现

一、基于Spring

1、配置类

import java.util.concurrent.Executor;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; /**
* @Description: 配置类实现AsyncConfigurer接口,并重写getAsyncExecutor方法,并返回一个ThreadPoolTaskExecutor,
* 这样我们就获得一个基于线程池TaskExecutor
* @ClassName: CustomMultiThreadingConfig
* @Author: OnlyMate
* @Date: 2018年9月21日 下午2:50:14
*/
@Configuration
@ComponentScan("com.only.mate.springboot.multithreading")
@EnableAsync//利用@EnableAsync注解开启异步任务支持
public class CustomMultiThreadingConfig implements AsyncConfigurer{ @Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
} @Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return AsyncConfigurer.super.getAsyncUncaughtExceptionHandler();
} }

2、创建线程任务

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; /**
* @Description: 创建线程任务服务
* @ClassName: CustomMultiThreadingService
* @Author: OnlyMate
* @Date: 2018年9月21日 下午3:17:57
*/
@Service
public class CustomMultiThreadingService {
private Logger logger = LoggerFactory.getLogger(CustomMultiThreadingService.class);
/**
* @Description:通过@Async注解表明该方法是一个异步方法,
* 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
* @Title: executeAysncTask1
* @Date: 2018年9月21日 下午2:54:32
* @Author: OnlyMate
* @Throws
* @param i
*/
@Async
public void executeAysncTask1(Integer i){
logger.info("CustomMultiThreadingService ==> executeAysncTask1 method: 执行异步任务{} ", i);
} /**
* @Description:通过@Async注解表明该方法是一个异步方法,
* 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
* @Title: executeAsyncTask2
* @Date: 2018年9月21日 下午2:55:04
* @Author: OnlyMate
* @Throws
* @param i
*/
@Async
public void executeAsyncTask2(Integer i){
logger.info("CustomMultiThreadingService ==> executeAsyncTask2 method: 执行异步任务{} ", i);
}
}

3、触发线程任务

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.only.mate.springboot.multithreading.CustomMultiThreadingService; /**
* @Description:自定义多线程Controller
* @ClassName: CustomMultiThreadingController
* @Author: OnlyMate
* @Date: 2018年9月21日 下午3:02:49
*/
@Controller
@RequestMapping(value="/multithreading")
public class CustomMultiThreadingController {
@Autowired
private CustomMultiThreadingService customMultiThreadingService; @ResponseBody
@RequestMapping(value="/dotask")
public String doTask() {
for (int i=0;i<10;i++){
customMultiThreadingService.executeAysncTask1(i);
customMultiThreadingService.executeAsyncTask2(i);
} return "success";
}
}

4、效果图

访问http://localhost:8088/springboot/multithreading/dotask

二、基于Java

1、异步线程调度管理器

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; /**
* @Description: 异步线程调度管理器
* @ClassName: CustomAsyncScheduler
* @Author: OnlyMate
* @Date: 2018年9月21日 下午3:25:40
*/
public class CustomAsyncScheduler {
private volatile static CustomAsyncScheduler instance;
private static ThreadPoolExecutor chnlBackendQueryPool; private CustomAsyncScheduler() {
} @SuppressWarnings({ "rawtypes", "static-access", "unchecked" })
public static CustomAsyncScheduler getInstance() {
if (instance == null) {
synchronized (CustomAsyncScheduler.class) {
if (instance == null) {
instance = new CustomAsyncScheduler(); BlockingQueue queue = new LinkedBlockingQueue();
chnlBackendQueryPool = new ThreadPoolExecutor(50, 100, 30, TimeUnit.SECONDS, queue);
chnlBackendQueryPool.allowCoreThreadTimeOut(true);
instance.setChnlBackendQueryPool(chnlBackendQueryPool);
}
}
}
return instance;
} public ThreadPoolExecutor getChnlBackendQueryPool() {
return chnlBackendQueryPool;
} public static void setChnlBackendQueryPool(ThreadPoolExecutor chnlBackendQueryPool) {
CustomAsyncScheduler.chnlBackendQueryPool = chnlBackendQueryPool;
} public static void setInstance(CustomAsyncScheduler instance) {
CustomAsyncScheduler.instance = instance;
} }

2、创建线程任务

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; /**
* @Description: 创建线程任务服务
* @ClassName: CustomMultiThreadingService
* @Author: OnlyMate
* @Date: 2018年9月21日 下午3:17:57
*/
@Service
public class CustomMultiThreadingService {
private Logger logger = LoggerFactory.getLogger(CustomMultiThreadingService.class);
/**
* @Description:通过@Async注解表明该方法是一个异步方法,
* 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
* @Title: executeAysncTask1
* @Date: 2018年9月21日 下午2:54:32
* @Author: OnlyMate
* @Throws
* @param i
*/
@Async
public void executeAysncTask1(Integer i){
logger.info("CustomMultiThreadingService ==> executeAysncTask1 method: 执行异步任务{} ", i);
} /**
* @Description:通过@Async注解表明该方法是一个异步方法,
* 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
* @Title: executeAsyncTask2
* @Date: 2018年9月21日 下午2:55:04
* @Author: OnlyMate
* @Throws
* @param i
*/
@Async
public void executeAsyncTask2(Integer i){
logger.info("CustomMultiThreadingService ==> executeAsyncTask2 method: 执行异步任务{} ", i);
} /**
* @Description: 异步线程调度管理器创建线程任务
* @Title: executeAsyncTask3
* @Date: 2018年9月21日 下午3:32:28
* @Author: OnlyMate
* @Throws
* @param i
*/
public void executeAsyncTask3(Integer i){
CustomAsyncScheduler.getInstance().getChnlBackendQueryPool().execute(new Runnable() {
@Override
public void run() {
logger.info("CustomMultiThreadingService ==> executeAsyncTask3 method: 执行异步任务{} ", i);
}
}); }
}

3、触发线程任务

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.only.mate.springboot.multithreading.CustomMultiThreadingService; /**
* @Description:自定义多线程Controller
* @ClassName: CustomMultiThreadingController
* @Author: OnlyMate
* @Date: 2018年9月21日 下午3:02:49
*/
@Controller
@RequestMapping(value="/multithreading")
public class CustomMultiThreadingController {
@Autowired
private CustomMultiThreadingService customMultiThreadingService; @ResponseBody
@RequestMapping(value="/dotask")
public String doTask() {
for (int i=0;i<10;i++){
customMultiThreadingService.executeAysncTask1(i);
customMultiThreadingService.executeAsyncTask2(i);
} return "success";
} @ResponseBody
@RequestMapping(value="/dojob")
public String doJob() {
for (int i=0;i<10;i++){
customMultiThreadingService.executeAysncTask1(i);
customMultiThreadingService.executeAsyncTask2(i);
customMultiThreadingService.executeAsyncTask3(i);
}
return "success";
}
}

4、效果图

访问http://localhost:8088/springboot/multithreading/dojob

Spring Boot实践——多线程的更多相关文章

  1. Spring Boot实践——Spring AOP实现之动态代理

    Spring AOP 介绍 AOP的介绍可以查看 Spring Boot实践——AOP实现 与AspectJ的静态代理不同,Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改 ...

  2. Spring Boot实践——AOP实现

    借鉴:http://www.cnblogs.com/xrq730/p/4919025.html     https://blog.csdn.net/zhaokejin521/article/detai ...

  3. Spring Boot 实践 :Spring Boot + MyBatis

    Spring Boot 实践系列,Spring Boot + MyBatis . 目的 将 MyBatis 与 Spring Boot 应用程序一起使用来访问数据库. 本次使用的Library spr ...

  4. spring boot 实践

    二.实践 一些说明: 项目IDE采用Intellij(主要原因在于Intellij颜值完爆Eclipse,谁叫这是一个看脸的时代) 工程依赖管理采用个人比较熟悉的Maven(事实上SpringBoot ...

  5. spring boot 实践总结(转)

    pring Boot是最流行的用于开发微服务的Java框架.在本文主要分享的是在专业开发中使用Spring Boot所采用的最佳实践.这些内容是基于个人经验和一些熟知的Spring Boot专家的文章 ...

  6. Spring Boot 定时+多线程执行

    Spring Boot 定时任务有多种实现方式,我在一个微型项目中通过注解方式执行定时任务. 具体执行的任务,通过多线程方式执行,单线程执行需要1小时的任务,多线程下5分钟就完成了. 执行效率提升10 ...

  7. Spring Boot实践——用外部配置填充Bean属性的几种方法

    引用:https://blog.csdn.net/qq_17586821/article/details/79802320 spring boot允许我们把配置信息外部化.由此,我们就可以在不同的环境 ...

  8. Spring Boot实践——事件监听

    借鉴:https://blog.csdn.net/Harry_ZH_Wang/article/details/79691994 https://blog.csdn.net/ignorewho/arti ...

  9. Spring Boot实践——基础和常用配置

    借鉴:https://blog.csdn.net/j903829182/article/details/74906948 一.Spring Boot 启动注解说明 @SpringBootApplica ...

随机推荐

  1. 局域网内web地图的简单实现

    首先,我先说一下这次的主要目的.我们的想法是在不连互联网的局域网中搭起来一个地图服务,类似于百度地图的网页版本,功能最少要有看地图.放缩.标记.批量标记.实时经纬度坐标.这个东西还是让我费了一番力气( ...

  2. 数论练习(5)——青蛙的约会(扩gcd)

    青蛙的约会 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 122502   Accepted: 26015 Descript ...

  3. Java——抽象类、接口

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  4. Winform开发常用控件之DataGridView的简单数据绑定——自动绑定

    DataGridView控件可谓是Winform开发的重点控件,对于数据的呈现和操作非常方便,DataGridView可谓是既简单又复杂.简单在于其已经集成了很多方法,复杂在于可以使用其实现复杂的数据 ...

  5. 关于SSL的error问题

    今天模拟网页版微信登录的时候又碰到一个SSLError的问题 requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SS ...

  6. Mac: iTerm2使用

    From: http://www.cnblogs.com/noTice520/p/3190529.html 之前一直有朋友要我分享下在用的mac软件,今天有空就来写一下,可能不止于软件,会有一些配置或 ...

  7. cratedb geo 查询

    cratedb支持的geo 查询还相对比较全,开发基本的功能已经够用了 安装cratedb 使用docker docker run -d -p 4200:4200 crate 创建数据库 创建表 CR ...

  8. 【转】嵌入式Linux启动配置文件及脚本

    原文网址:http://blog.csdn.net/shuaishuai80/article/details/6202497 使用Busybox制作根文件系统时,/etc目录非常重要,它包含了嵌入式L ...

  9. xmlns和xsi之schemaLocation

    appplicationContex.xml文件报错:元素 "util:constant" 的前缀 "util" 未绑定 在根节点添加了“xmlns:util= ...

  10. 解决移动端H5海报滑动插件适应大部分手机问题 手机端高度自适应

    Html5微信端滑屏海报在各种尺寸的手机上总会有这样那样的问题,经过多次制作总结出来一些小心得,分享下. 我使用的是jquery插件swiper.min.js,动画可以利用animate.css,如果 ...