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 ...
随机推荐
- Python的文件读写与存储
文件读写与存储 7.2. 读写文件 open()返回一个文件对象,最常见的用法带有两个参数:open(filename, mode). >>> f = open('workfile' ...
- 用nc做网络压力测试
测试结果: 1.数据的收发正常,没有出现丢包: 2.平均数据接发速率为:112MB/S,基本用完的千兆带宽. 测试方法: 1.通过FTP拷贝3.6G ...
- PHP开发环境MAMP for Windows
Windows上的整合PHP开发环境有很多,如:Windows上使用的Wampserver(http://www.wampserver.com/),跨平台的Xampp(https://www.apac ...
- 【P2401】不等数列(DP)
这个题乍一看就应该是DP,再看一眼数据范围,1000..那就应该是了.然后就向DP的方向想,经过对小数据的计算可以得出,如果我们用f[i][j]来表示前i个数有j个是填了"<" ...
- Android深度探索(卷1)HAL与驱动开发 虚拟环境的安装
前言: 最近在看<Android深度探索(卷1)HAL与驱动开发>安装随书带的虚拟环境浪费了很多时间,说是虚拟环境的安装倒不如说是虚拟环境的导入,其实没什么技术含量,也没有什么复杂的,只是 ...
- Hadoop学习1(初识hadoop)
Hadoop生态系统的特点 1)源代码开源 2)社区活跃,参与者多 3)涉及分布式存储和计算的各方面 4)已得到企业界的验证 Hadoop构成 1) 分布式文件系统HDFS(Hadoop Distri ...
- 电子商务的几种模式,b2b,c2c等
B2B(Business to Business) ——这是指商家与商家建立的商业关系.(最早的一种模式) C2C (Customer to Consumer) ——个人与个人的商业关系,也就是消费者 ...
- Django中间件的总结
一.中间件 --中间件是一个轻量级.底层的插件系统,可以加入Django的请求和响应过程,修改Django的输入和输出 --每一个中间件组件是一个独立的Python类,可以定义下面方法中的一个和多个 ...
- JNI_Z
1. ZC: 用到 VC6 ... http://blog.csdn.net/jiangwei0910410003/article/details/17465085 http://blog.csdn. ...
- review35
使用Thread创建线程通常使用的方法是:Thread(Runnable target).该构造方法中的参数是一个Runnable类型的接口,因此在创建线程对象时必须向构造方法的参数传递一个实现Run ...