Spring线程池开发实战

作者:chszs,转载需注明。

作者博客主页: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

  1. package com.chszs.thread;
  2. import org.springframework.stereotype.Component;
  3. import org.springframework.context.annotation.Scope;
  4. @Component
  5. @Scope("prototype")
  6. public class PrintThread extends Thread{
  7. @Override
  8. public void run(){
  9. System.out.println(getName() + " is running.");
  10. try{
  11. Thread.sleep(5000);
  12. }catch(InterruptedException e){
  13. e.printStackTrace();
  14. }
  15. System.out.println(getName() + " is running again.");
  16. }
  17. }

AppConfig.java

  1. package com.chszs.config;
  2. import org.springframework.context.annotation.ComponentScan;
  3. import org.springframework.context.annotation.Configuration;
  4. @Configuration
  5. @ComponentScan(basePackages="com.chszs.thread")
  6. public class AppConfig {
  7. }

App.java

  1. package com.chszs;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  4. import com.chszs.config.AppConfig;
  5. import com.chszs.thread.PrintThread;
  6. public class App {
  7. public static void main(String[] args){
  8. ApplicationContext ctx =
  9. new AnnotationConfigApplicationContext(AppConfig.class);
  10. PrintThread printThread1 = (PrintThread)ctx.getBean("printThread");
  11. printThread1.setName("Thread 1");
  12. PrintThread printThread2 = (PrintThread)ctx.getBean("printThread");
  13. printThread2.setName("Thread 2");
  14. PrintThread printThread3 = (PrintThread)ctx.getBean("printThread");
  15. printThread3.setName("Thread 3");
  16. PrintThread printThread4 = (PrintThread)ctx.getBean("printThread");
  17. printThread4.setName("Thread 4");
  18. PrintThread printThread5 = (PrintThread)ctx.getBean("printThread");
  19. printThread5.setName("Thread 5");
  20. printThread1.start();
  21. printThread2.start();
  22. printThread3.start();
  23. printThread4.start();
  24. printThread5.start();
  25. }
  26. }

输出:

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

  1. package com.chszs.thread;
  2. public class PrintTask implements Runnable{
  3. String name;
  4. public PrintTask(String name){
  5. this.name = name;
  6. }
  7. @Override
  8. public void run() {
  9. System.out.println(name + " is running.");
  10. try{
  11. Thread.sleep(5000);
  12. }catch(InterruptedException e){
  13. e.printStackTrace();
  14. }
  15. System.out.println(name + " is running again.");
  16. }
  17. }

Spring-Config.xml

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  6. http://www.springframework.org/schema/context
  7. http://www.springframework.org/schema/context/spring-context-3.1.xsd">
  8. <bean id="taskExecutor"
  9. class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
  10. <property name="corePoolSize" value="5" />
  11. <property name="maxPoolSize" value="10" />
  12. <property name="WaitForTasksToCompleteOnShutdown" value="true" />
  13. </bean>
  14. </beans>

注意这个Spring配置文件的位置,如图所示:

App1.java

  1. package com.chszs;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  5. import com.chszs.thread.PrintTask;
  6. public class App1 {
  7. public static void main(String[] args) {
  8. ApplicationContext ctx =
  9. new ClassPathXmlApplicationContext("resources/Spring-Config.xml");
  10. ThreadPoolTaskExecutor taskExecutor =
  11. (ThreadPoolTaskExecutor)ctx.getBean("taskExecutor");
  12. taskExecutor.execute(new PrintTask("Thread 1"));
  13. taskExecutor.execute(new PrintTask("Thread 2"));
  14. taskExecutor.execute(new PrintTask("Thread 3"));
  15. taskExecutor.execute(new PrintTask("Thread 4"));
  16. taskExecutor.execute(new PrintTask("Thread 5"));
  17. // 检查活动的线程,如果活动线程数为0则关闭线程池
  18. for(;;){
  19. int count = taskExecutor.getActiveCount();
  20. System.out.println("Active Threads : " + count);
  21. try{
  22. Thread.sleep(1000);
  23. }catch(InterruptedException e){
  24. e.printStackTrace();
  25. }
  26. if(count==0){
  27. taskExecutor.shutdown();
  28. break;
  29. }
  30. }
  31. }
  32. }

输出:

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

  1. package com.chszs.thread;
  2. import org.springframework.context.annotation.Scope;
  3. import org.springframework.stereotype.Component;
  4. @Component
  5. @Scope("prototype")
  6. public class PrintTask2 implements Runnable {
  7. String name;
  8. public void setName(String name) {
  9. this.name = name;
  10. }
  11. @Override
  12. public void run(){
  13. System.out.println(name + " is running.");
  14. try{
  15. Thread.sleep(5000);
  16. }catch(InterruptedException e){
  17. e.printStackTrace();
  18. }
  19. System.out.println(name + " is running again.");
  20. }
  21. }

AppConfig.java

  1. package com.chszs.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.ComponentScan;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  6. @Configuration
  7. @ComponentScan(basePackages="com.chszs.thread")
  8. public class AppConfig {
  9. @Bean
  10. public ThreadPoolTaskExecutor taskExecutor(){
  11. ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
  12. pool.setCorePoolSize(5);
  13. pool.setMaxPoolSize(10);
  14. pool.setWaitForTasksToCompleteOnShutdown(true);
  15. return pool;
  16. }
  17. }

App2.java

  1. package com.chszs;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  4. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  5. import com.chszs.config.AppConfig;
  6. import com.chszs.thread.PrintTask2;
  7. public class App2 {
  8. public static void main(String[] args) {
  9. ApplicationContext ctx =
  10. new AnnotationConfigApplicationContext(AppConfig.class);
  11. ThreadPoolTaskExecutor taskExecutor =
  12. (ThreadPoolTaskExecutor)ctx.getBean("taskExecutor");
  13. PrintTask2 printTask1 = (PrintTask2)ctx.getBean("printTask2");
  14. printTask1.setName("Thread 1");
  15. taskExecutor.execute(printTask1);
  16. PrintTask2 printTask2 = (PrintTask2)ctx.getBean("printTask2");
  17. printTask2.setName("Thread 2");
  18. taskExecutor.execute(printTask2);
  19. PrintTask2 printTask3 = (PrintTask2)ctx.getBean("printTask2");
  20. printTask3.setName("Thread 3");
  21. taskExecutor.execute(printTask3);
  22. for(;;){
  23. int count = taskExecutor.getActiveCount();
  24. System.out.println("Active Threads : " + count);
  25. try{
  26. Thread.sleep(1000);
  27. }catch(InterruptedException e){
  28. e.printStackTrace();
  29. }
  30. if(count==0){
  31. taskExecutor.shutdown();
  32. break;
  33. }
  34. }
  35. }
  36. }

输出:

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线程池开发实战的更多相关文章

  1. Spring线程池由浅入深的3个示例

    作者博客主页:http://blog.csdn.net/chszs 本文提供了三个Spring多线程开发的例子,由浅入深,由于例子一目了然,所以并未做过多的解释.诸位一看便知. 前提条件: 1)在Ec ...

  2. Spring线程池配置模板设计(基于Springboot)

    目录 线程池配置模板 基础的注解解释 常用配置参数 配置类设计 线程池使用 ThreadPoolTaskExecutor源码 线程池配置模板 springboot给我们提供了一个线程池的实现,它的底层 ...

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

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

  4. 分享知识-快乐自己:Spring线程池配置

    Spring通过ThreadPoolTaskExecutor实现线程池技术,它是使用jdk中的Java.util.concurrent.ThreadPoolExecutor进行实现. Spring 配 ...

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

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

  6. spring线程池的同步和异步(1)

    spring线程池(同步.异步) 一.spring异步线程池类图 二.简单介绍 2.1. TaskExecutor---Spring异步线程池的接口类,其实质是java.util.concurrent ...

  7. 007-多线程-JUC线程池-Spring线程池配置、池子如何配置参数

    一.概述 Spring通过ThreadPoolTaskExecutor实现线程池技术,它是使用jdk中的Java.util.concurrent.ThreadPoolExecutor进行实现. 1.1 ...

  8. JDK线程池和Spring线程池的使用

    JDK线程池和Spring线程池实例,异步调用,可以直接使用 (1)JDK线程池的使用,此处采用单例的方式提供,见示例: public class ThreadPoolUtil { private s ...

  9. java和spring 线程池总结

    1. spring 的线程池 ThreadPoolTaskExecutor @Configuration public class ThreadPoolConfig { @Bean("thr ...

随机推荐

  1. angular.js跨域post解决方案

    跨域,前端开发中经常遇到的问题,AngularJS实现跨域方式类似于Ajax,使用CORS机制. 下面阐述一下AngularJS中使用$http实现跨域请求数据. AngularJS XMLHttpR ...

  2. PHP编程----猴子选大王

    <?php/** * 猴子选大王 * 17个猴子围成一圈,从某个开始报数1-2-3-1-2-3---报"3"的猴子就被淘汰, * 游戏一直进行到圈内只剩一只猴子它就是猴大王了 ...

  3. 批量安装XP补丁的命令

    方法一: 新建一个bat文件,把这个文件和所有补丁文件放在同一个目录下,双击运行. BAT代码如下 @echo offfor %%i in (*.exe) do %%i /passive /nores ...

  4. (转载)#include机制,#ifndef...#define...#endif防止重复引用,声明,定义等概念

    一.来自百度知道的问题:全局变量可以声明定义在头文件中? 答案: 注意头文件中不可以放变量的定义!!!一般情况下头文件中只放变量的声明,因为头文件要被其他文件包含(即#include).如果把定义放到 ...

  5. Struts2第二天

    Struts2第二天 昨天: 1.Action的编写方式:实现Action接口.继承ActionSupport.自定义pojo作为action 2.action调用方法:默认的execute.meth ...

  6. Nginx1.8.0版本平滑升级新版本1.9.7

    原文:http://www.jb51.net/article/79878.htm 首先查看现在环境nginx的版本为1.8.0 编译的参数只指定了安装路径: 复制代码代码如下: [root@local ...

  7. python websocket学习使用

    前言 今天看了一些资料,记录一下心得. websocket是html5引入的一个新特性,传统的web应用是通过http协议来提供支持,如果要实时同步传输数据,需要轮询,效率低下 websocket是类 ...

  8. 5、判断、循环、数组综合练习案例(迷你DVD)

    迷你dvd代码如下: package com.manager; import java.util.Scanner; public class DVDManage { public static voi ...

  9. Django中的ORM

    Django中ORM的使用. 一.安装python连接mysql的模块:MySQL-python sudo pip install MySQL-python 安装完成后在python-shell中测试 ...

  10. jsonp原来是这么回事,豁然开朗

    什么是JSONP 先说说JSONP是怎么产生的: 其实网上关于JSONP的讲解有很多,但却千篇一律,而且云里雾里,对于很多刚接触的人来讲理解起来有些困难,小可不才,试着用自己的方式来阐释一下这个问题, ...