Spring线程池由浅入深的3个示例
作者博客主页:http://blog.csdn.net/chszs
本文提供了三个Spring多线程开发的例子,由浅入深,由于例子一目了然,所以并未做过多的解释。诸位一看便知。
前提条件:
1)在Eclipse创建一个Java项目,我取名为SpringThreadDemo。
2)项目所需的JAR包如图所示:

下面开始。
注:项目源码已经托管到GitHub,地址:https://github.com/chszs/SpringThreadDemo
例子1:Spring结合Java线程。
通过继承Thread创建一个简单的Java线程,然后使用@Component让Spring容器管理此线程,Bean的范围必须是prototype,因此每个请求都会返回一个新实例,运行每个单独的线程。
PrintThread.java
- package com.chszs.thread;
- import org.springframework.stereotype.Component;
- import org.springframework.context.annotation.Scope;
- @Component
- @Scope("prototype")
- public class PrintThread extends Thread{
- @Override
- public void run(){
- System.out.println(getName() + " is running.");
- try{
- Thread.sleep(5000);
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- System.out.println(getName() + " is running again.");
- }
- }
AppConfig.java
- package com.chszs.config;
- import org.springframework.context.annotation.ComponentScan;
- import org.springframework.context.annotation.Configuration;
- @Configuration
- @ComponentScan(basePackages="com.chszs.thread")
- public class AppConfig {
- }
App.java
- package com.chszs;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.annotation.AnnotationConfigApplicationContext;
- import com.chszs.config.AppConfig;
- import com.chszs.thread.PrintThread;
- public class App {
- public static void main(String[] args){
- ApplicationContext ctx =
- new AnnotationConfigApplicationContext(AppConfig.class);
- PrintThread printThread1 = (PrintThread)ctx.getBean("printThread");
- printThread1.setName("Thread 1");
- PrintThread printThread2 = (PrintThread)ctx.getBean("printThread");
- printThread2.setName("Thread 2");
- PrintThread printThread3 = (PrintThread)ctx.getBean("printThread");
- printThread3.setName("Thread 3");
- PrintThread printThread4 = (PrintThread)ctx.getBean("printThread");
- printThread4.setName("Thread 4");
- PrintThread printThread5 = (PrintThread)ctx.getBean("printThread");
- printThread5.setName("Thread 5");
- printThread1.start();
- printThread2.start();
- printThread3.start();
- printThread4.start();
- printThread5.start();
- }
- }
输出:
Thread 1 is running.
Thread 2 is running.
Thread 4 is running.
Thread 5 is running.
Thread 3 is running.
Thread 2 is running again.
Thread 1 is running again.
Thread 5 is running again.
Thread 4 is running again.
Thread 3 is running again.
例子2:Spring线程池结合非Spring托管Bean。
使用Spring的ThreadPoolTaskExecutor类创建一个线程池。执行线程无需受Spring容器的管理。
PrintTask.java
- package com.chszs.thread;
- public class PrintTask implements Runnable{
- String name;
- public PrintTask(String name){
- this.name = name;
- }
- @Override
- public void run() {
- System.out.println(name + " is running.");
- try{
- Thread.sleep(5000);
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- System.out.println(name + " is running again.");
- }
- }
Spring-Config.xml
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.1.xsd">
- <bean id="taskExecutor"
- class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
- <property name="corePoolSize" value="5" />
- <property name="maxPoolSize" value="10" />
- <property name="WaitForTasksToCompleteOnShutdown" value="true" />
- </bean>
- </beans>
注意这个Spring配置文件的位置,如图所示:

App1.java
- package com.chszs;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
- import com.chszs.thread.PrintTask;
- public class App1 {
- public static void main(String[] args) {
- ApplicationContext ctx =
- new ClassPathXmlApplicationContext("resources/Spring-Config.xml");
- ThreadPoolTaskExecutor taskExecutor =
- (ThreadPoolTaskExecutor)ctx.getBean("taskExecutor");
- taskExecutor.execute(new PrintTask("Thread 1"));
- taskExecutor.execute(new PrintTask("Thread 2"));
- taskExecutor.execute(new PrintTask("Thread 3"));
- taskExecutor.execute(new PrintTask("Thread 4"));
- taskExecutor.execute(new PrintTask("Thread 5"));
- // 检查活动的线程,如果活动线程数为0则关闭线程池
- for(;;){
- int count = taskExecutor.getActiveCount();
- System.out.println("Active Threads : " + count);
- try{
- Thread.sleep(1000);
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- if(count==0){
- taskExecutor.shutdown();
- break;
- }
- }
- }
- }
输出:
Thread 1 is running.
Thread 2 is running.
Thread 3 is running.
Thread 4 is running.
Active Threads : 4
Thread 5 is running.
Active Threads : 5
Active Threads : 5
Active Threads : 5
Active Threads : 5
Active Threads : 5
Thread 4 is running again.
Thread 2 is running again.
Thread 3 is running again.
Thread 1 is running again.
Thread 5 is running again.
Active Threads : 0
作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszs
例子3:Spring线程池结合Spring托管Bean。
本例仍然使用ThreadPoolTaskExecutor类,并使用@Component注释声明Spring的托管Bean。
下面的例子PrintTask2是Spring的托管Bean,使用@Autowired注释简化代码。
PrintTask2.java
- package com.chszs.thread;
- import org.springframework.context.annotation.Scope;
- import org.springframework.stereotype.Component;
- @Component
- @Scope("prototype")
- public class PrintTask2 implements Runnable {
- String name;
- public void setName(String name) {
- this.name = name;
- }
- @Override
- public void run(){
- System.out.println(name + " is running.");
- try{
- Thread.sleep(5000);
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- System.out.println(name + " is running again.");
- }
- }
AppConfig.java
- package com.chszs.config;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.ComponentScan;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
- @Configuration
- @ComponentScan(basePackages="com.chszs.thread")
- public class AppConfig {
- @Bean
- public ThreadPoolTaskExecutor taskExecutor(){
- ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
- pool.setCorePoolSize(5);
- pool.setMaxPoolSize(10);
- pool.setWaitForTasksToCompleteOnShutdown(true);
- return pool;
- }
- }
App2.java
- package com.chszs;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.annotation.AnnotationConfigApplicationContext;
- import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
- import com.chszs.config.AppConfig;
- import com.chszs.thread.PrintTask2;
- public class App2 {
- public static void main(String[] args) {
- ApplicationContext ctx =
- new AnnotationConfigApplicationContext(AppConfig.class);
- ThreadPoolTaskExecutor taskExecutor =
- (ThreadPoolTaskExecutor)ctx.getBean("taskExecutor");
- PrintTask2 printTask1 = (PrintTask2)ctx.getBean("printTask2");
- printTask1.setName("Thread 1");
- taskExecutor.execute(printTask1);
- PrintTask2 printTask2 = (PrintTask2)ctx.getBean("printTask2");
- printTask2.setName("Thread 2");
- taskExecutor.execute(printTask2);
- PrintTask2 printTask3 = (PrintTask2)ctx.getBean("printTask2");
- printTask3.setName("Thread 3");
- taskExecutor.execute(printTask3);
- for(;;){
- int count = taskExecutor.getActiveCount();
- System.out.println("Active Threads : " + count);
- try{
- Thread.sleep(1000);
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- if(count==0){
- taskExecutor.shutdown();
- break;
- }
- }
- }
- }
输出:
Thread 1 is running.
Thread 2 is running.
Active Threads : 2
Thread 3 is running.
Active Threads : 3
Active Threads : 3
Active Threads : 3
Active Threads : 3
Thread 1 is running again.
Thread 2 is running again.
Thread 3 is running again.
Active Threads : 1
Active Threads : 0
从这三个简单的实例中,你是不是发现了Spring框架在多线程方面的强大之处!!
Spring线程池由浅入深的3个示例的更多相关文章
- Spring线程池开发实战
Spring线程池开发实战 作者:chszs,转载需注明. 作者博客主页:http://blog.csdn.net/chszs 本文提供了三个Spring多线程开发的例子,由浅入深,由于例子一目了然, ...
- Spring线程池ThreadPoolTaskExecutor配置及详情
Spring线程池ThreadPoolTaskExecutor配置及详情 1. ThreadPoolTaskExecutor配置 <!-- spring thread pool executor ...
- JDK线程池和Spring线程池的使用
JDK线程池和Spring线程池实例,异步调用,可以直接使用 (1)JDK线程池的使用,此处采用单例的方式提供,见示例: public class ThreadPoolUtil { private s ...
- Spring线程池配置模板设计(基于Springboot)
目录 线程池配置模板 基础的注解解释 常用配置参数 配置类设计 线程池使用 ThreadPoolTaskExecutor源码 线程池配置模板 springboot给我们提供了一个线程池的实现,它的底层 ...
- 分享知识-快乐自己:Spring线程池配置
Spring通过ThreadPoolTaskExecutor实现线程池技术,它是使用jdk中的Java.util.concurrent.ThreadPoolExecutor进行实现. Spring 配 ...
- 【SSM Spring 线程池 OJ】 使用Spring线程池ThreadPoolTaskExecutor
最近做的Online Judge项目,在本地判题的实现过程中,遇到了一些问题,包括多线程,http通信等等.现在完整记录如下: OJ有一个业务是: 用户在前端敲好代码,按下提交按钮发送一个判题请求给后 ...
- spring线程池的同步和异步(1)
spring线程池(同步.异步) 一.spring异步线程池类图 二.简单介绍 2.1. TaskExecutor---Spring异步线程池的接口类,其实质是java.util.concurrent ...
- 007-多线程-JUC线程池-Spring线程池配置、池子如何配置参数
一.概述 Spring通过ThreadPoolTaskExecutor实现线程池技术,它是使用jdk中的Java.util.concurrent.ThreadPoolExecutor进行实现. 1.1 ...
- spring线程池配置
源自:http://zjriso.iteye.com/blog/771706 1.了解 TaskExecutor接口 Spring的TaskExecutor接口等同于java.util.concurr ...
随机推荐
- 《机器学习实战第7章:利用AdaBoost元算法提高分类性能》
import numpy as np import matplotlib.pyplot as plt def loadSimpData(): dataMat = np.matrix([[1., 2.1 ...
- mongodb 中 Aggregation 的管道和分片集合( Pipeline and Sharded Collections)
mongodb 中的aggretion 中,如果管道中存在一个与之相匹配的shard key ,那么这个管道只运行在与之相匹配的shard 中,在以前(3.2),pipeline 被分流,最后又由pr ...
- Bootstrap3组件--1
目录 1. Glyphicons字体图标 2.下拉菜单 3.按钮组 4. 输入框组 5.导航 6. 导航条 7. 路径导航 1. Glyphicons字体图标 出于性能的考虑,所有图标都需要一个基类 ...
- 山东省第六届ACM省赛 H---Square Number 【思考】
题目描述 In mathematics, a square number is an integer that is the square of an integer. In other words, ...
- java深入探究09-Filter,Listener,国际化
1.Filter过滤器 1)为是么有过滤器 开发项目中经常遇到直接登录主页面要判断用户是否合法,这类代码比较重复,可以通过过滤器来解决 2)过滤器原理生命周期 服务器创建过滤器对象->一个执行i ...
- ggplot笔记002——qplot()函数
qplot()函数 一年前就听说过ggplot,很多人都说ggplot强大,ggplot无所不能,从今天开始就让我们一起来见证一下这个神奇的R包. 首先要加载ggplot2: 1 if(!suppre ...
- Qt5.3.2_vs10_发布时所需DLL的路径
1. ???\Qt5.3.2_vs2010\5.3\msvc2010_opengl\bin 2.
- 一道问题引出的python中可变数据类型与不可变数据类型
一. 问题的提出 我们先来看两个对比 第一道题,当对象为整数时,最终结果:b = 2, a = 1,b的变化没有引起a的变化 a = 1 b = a b += 1 print(a) print(b) ...
- ural 2021 Scarily interesting!(贪心)
2021. Scarily interesting! Time limit: 1.0 secondMemory limit: 64 MB This year at Monsters Universit ...
- vue-router使用next()跳转到指定路径时会无限循环
我在路由为 /path 的页面这样写 beforeRouteLeave (to, from, next) { console.log('离开路路由') if(to.fullPath==='/home' ...