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
 
- 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"));  
 
-                 
 
-                 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线程池开发实战
原文:http://www.cnblogs.com/huangpeng1990/p/4570590.html