Spring线程池开发实战

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

[java] view plaincopyprint?

  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

[java] view plaincopyprint?

  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

[java] view plaincopyprint?

  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

[java] view plaincopyprint?

  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

[html] view plaincopyprint?

  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

[java] view plaincopyprint?

  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

[java] view plaincopyprint?

  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

[java] view plaincopyprint?

  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

[java] view plaincopyprint?

  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框架在多线程方面的强大之处!!

时间: 2025-01-01 19:10:55

Spring线程池开发实战的相关文章

Spring线程池开发实战及使用spring注解

本文提供了三个Spring多线程开发的例子,由浅入深,由于例子一目了然,所以并未做过多的解释.诸位一看便知. 前提条件: 1)在Eclipse创建一个Java项目,我取名为SpringThreadDemo.2)项目所需的JAR包如图所示:  下面开始. 注:项目源码已经托管到GitHub,地址:https://github.com/chszs/SpringThreadDemo 例子1:Spring结合Java线程. 通过继承Thread创建一个简单的Java线程,然后使用@Component让S

spring线程池配置

源自:http://zjriso.iteye.com/blog/771706 1.了解 TaskExecutor接口 Spring的TaskExecutor接口等同于java.util.concurrent.Executor接口. 实际上,它存在的主要原因是为了在使用线程池的时候,将对Java 5的依赖抽象出来. 这个接口只有一个方法execute(Runnable task),它根据线程池的语义和配置,来接受一个执行任务.最初创建TaskExecutor是为了在需要时给其他Spring组件提供

Springboot线程池服务实战分享

我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务:实战环境windowns10:jdk1.8:springboot 1.5.9.RELEASE:开发工具:IntelliJ IDEA: 这里面有多个工程,本次用到的工程为threadpooldemoserver,如下图红框所示:实战步骤梳理本次实战的步骤如下:创建springboot工程:创建Servic

java和spring 线程池总结

1. spring 的线程池 ThreadPoolTaskExecutor @Configuration public class ThreadPoolConfig { @Bean("threadPoolTaskExecutor") public ThreadPoolTaskExecutor threadPoolTaskExecutor(){ ThreadPoolTaskExecutor threadPoolTaskExecutor=new ThreadPoolTaskExecutor

spring线程池ThreadPoolTaskExecutor与阻塞队列BlockingQueue

一: ThreadPoolTaskExecutor是一个spring的线程池技术,查看代码可以看到这样一个字段: private ThreadPoolExecutor threadPoolExecutor; 可以发现,spring的  ThreadPoolTaskExecutor是使用的jdk中的java.util.concurrent.ThreadPoolExecutor进行实现, 直接看代码: @Override protected ExecutorService initializeExe

spring 线程池 的一个坑。

问题简述: 配置的队列初始化的消费者线程占满了线程池.导致其他的再使用此线程池中线程不运行.不报错,不抛异常.线程的数量仅为为线程池的配置中的最小值. <task:executor pool-size="100-150" queue-capacity="250" > 同时schema描述中写道: The size of the executor's thread pool as either a single value or a range    (e

Spring线程池的5个要素

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "/spring-beans.dtd"> <beans> <!-- 异步线程池 -->   <bean id="threadPool" class="org.spring

spring 线程池执行器DefaultManagedTaskScheduler之jndi

package com.example.spring.async.config; import java.util.concurrent.Executors; import javax.naming.NamingException; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springf

Spring线程池ThreadPoolTaskExecutor

一. ThreadPoolTaskExecutor 配置 <bean id ="taskExecutor"  class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >     <!-- 线程池维护线程的最少数量 -->     <property name ="corePoolSize" value ="5"