spring @scheduled并发

1、基于springboot的项目开启自动配置

 

[java]  view plain  copy
 
  1. package com.plateno.booking.sync.vienna;  
  2.   
  3.   
  4. import javax.annotation.PostConstruct;  
  5. import javax.jms.ConnectionFactory;  
  6.   
  7.   
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9. import org.springframework.boot.SpringApplication;  
  10. import org.springframework.boot.autoconfigure.SpringBootApplication;  
  11. import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;  
  12. import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;  
  13. import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;  
  14. import org.springframework.context.annotation.Bean;  
  15. import org.springframework.context.annotation.ImportResource;  
  16. import org.springframework.data.redis.core.RedisTemplate;  
  17. import org.springframework.jms.config.DefaultJmsListenerContainerFactory;  
  18. import org.springframework.jms.config.JmsListenerContainerFactory;  
  19. import org.springframework.jms.core.JmsTemplate;  
  20. import org.springframework.jms.support.converter.MessageConverter;  
  21. import org.springframework.scheduling.annotation.EnableAsync;  
  22. import org.springframework.scheduling.annotation.EnableScheduling;  
  23.   
  24.   
  25. import com.plateno.booking.sync.vienna.annotation.EnableMysql;  
  26. import com.plateno.booking.sync.vienna.annotation.EnableRedis;  
  27. import com.plateno.booking.sync.vienna.jms.messageconverter.PlatenoMessageConverter;  
  28. import com.plateno.booking.sync.vienna.util.BookingRedisHelper;  
  29. import com.plateno.booking.sync.vienna.util.SpringContextUtils;  
  30. //@EnableMysql  
  31. //@EnableRedis  
  32. //开启自动配置  
  33. @SpringBootApplication(exclude = {   
  34.         DataSourceAutoConfiguration.class,  
  35.         RedisAutoConfiguration.class  
  36.         }, scanBasePackageClasses = {  
  37.         BookingSyncVienna.class })  
  38. public class BookingSyncVienna {  
  39.       
  40.   
  41.   
  42.     public static void main(String[] args) {  
  43.         SpringApplication springApplication = new SpringApplication(BookingSyncVienna.class);  
  44.         springApplication.run(args);  
  45.     }  
  46.   
  47.   
  48.     @Autowired  
  49.     JmsTemplate jmsTemplate;  
  50.   
  51.   
  52.     @Bean  
  53.     MessageConverter messageConverter() {  
  54.         return new PlatenoMessageConverter();  
  55.     }  
  56.   
  57.   
  58.     @Bean  
  59.     SpringContextUtils springContextUtils() {  
  60.         return new SpringContextUtils();  
  61.     }  
  62.   
  63.   
  64.     @PostConstruct  
  65.     public void init() {  
  66.         this.jmsTemplate.setMessageConverter(messageConverter());  
  67.     }  
  68.   
  69.   
  70.     /** 
  71.      * 创建默认的listerFactory  
  72.      * see:JmsListenerAnnotationBeanPostProcessor->static final String DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME = "jmsListenerContainerFactory"; 
  73.      * @param connectionFactory 
  74.      * @param configurer 
  75.      * @return 
  76.      */  
  77.     @Bean(name="jmsListenerContainerFactory")  
  78.     public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,  
  79.             DefaultJmsListenerContainerFactoryConfigurer configurer) {  
  80.         DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();  
  81.         factory.setMessageConverter(messageConverter());  
  82.         configurer.configure(factory, connectionFactory);  
  83.         return factory;  
  84.     }  
  85.   
  86.   
  87. /*  @Bean 
  88.     @Autowired 
  89.     public BookingRedisHelper redisHelper(RedisTemplate redisTemplate) { 
  90.         BookingRedisHelper bookingRedisHelper = new BookingRedisHelper(); 
  91.         bookingRedisHelper.setRedisTemplate(redisTemplate); 
  92.         return bookingRedisHelper; 
  93.     } 
  94. */  
  95.     /* 
  96.      * @Bean public DefaultJmsListenerContainerFactory 
  97.      * listenerContainerFactory() { DefaultJmsListenerContainerFactory factory = 
  98.      * new DefaultJmsListenerContainerFactory(); 
  99.      * factory.setConnectionFactory(connectionFactory()); 
  100.      * factory.setMessageConverter(objectConverter()); 
  101.      * factory.setConcurrency("5"); return factory; } 
  102.      */  
  103.     /* 
  104.      * @Bean public ConnectionFactory connectionFactory(){ 
  105.      * PooledConnectionFactory pooledConnectionFactory = new 
  106.      * PooledConnectionFactory(); ActiveMQConnectionFactory mqConnectionFactory 
  107.      * = new ActiveMQConnectionFactory(); 
  108.      * mqConnectionFactory.setBrokerURL(brokerUrl); 
  109.      * mqConnectionFactory.setUseAsyncSend(true); 
  110.      * mqConnectionFactory.setOptimizeAcknowledgeTimeOut(3000); 
  111.      * pooledConnectionFactory.setConnectionFactory(mqConnectionFactory); 
  112.      * pooledConnectionFactory.setMaxConnections(20); 
  113.      * mqConnectionFactory.setTransactedIndividualAck(true); return 
  114.      * pooledConnectionFactory; } 
  115.      */  
  116. }  



 

 

2、创建作业类

[java]  view plain  copy
 
  1. package com.plateno.booking.sync.vienna.test;  
  2.   
  3.   
  4. import org.slf4j.Logger;  
  5. import org.slf4j.LoggerFactory;  
  6. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
  7. import org.springframework.scheduling.annotation.Async;  
  8. import org.springframework.scheduling.annotation.Scheduled;  
  9. import org.springframework.stereotype.Component;  
  10.   
  11. import com.plateno.booking.sync.vienna.properties.CronProperties;  
  12.   
  13. @Component  
  14. @ConditionalOnProperty(prefix = "", name = "test", havingValue = "true")  
  15. public class TestJob {  
  16.       
  17.     private static Logger logger = LoggerFactory.getLogger(TestJob.class);  
  18.       
  19.     @Scheduled(cron="0/2 * * * * ?")  
  20.     @Async//异步执行,配合线程池实现并发  
  21.     public void test(){  
  22.           
  23.         System.err.println("---------------------");  
  24.         System.err.println("a");  
  25.         logger.error(Thread.currentThread().getName());  
  26.         System.err.println("---------------------");  
  27.         try {  
  28.             Thread.sleep(20000);//执行睡眠,这样如果并发执行,那么上面的打印会2秒执行一次,而下面的ffff则会22秒打印一次  
  29.             System.out.println("ffff");  
  30.         } catch (InterruptedException e) {  
  31.             // TODO Auto-generated catch block  
  32.             e.printStackTrace();  
  33.         }  
  34.     }  
  35.       
  36.       
  37.     /*@Scheduled(cron="0/1 * * * * ?") 
  38.     public void test1(){ 
  39.         System.err.println("---------------------"); 
  40.         System.err.println("b"); 
  41.         logger.error(Thread.currentThread().getName()); 
  42.         System.err.println("---------------------"); 
  43.     }*/  
  44. }  


3、定义线程池配置文件(@enableSchedulling@scheduled默认是基于单线程),多线程并发需要配置xml

[html]  view plain  copy
 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:context="http://www.springframework.org/schema/context"  
  5.        xmlns:task="http://www.springframework.org/schema/task"  
  6.        xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.             http://www.springframework.org/schema/beans/spring-beans-4.2.xsd  
  8.             http://www.springframework.org/schema/context  
  9.             http://www.springframework.org/schema/context/spring-context-4.2.xsd  
  10.             http://www.springframework.org/schema/task  
  11.             http://www.springframework.org/schema/task/spring-task-4.2.xsd">  
  12.   
  13.  <task:scheduler id="scheduler" pool-size="10" />  
  14. <task:executor id="executor" keep-alive="7200" pool-size="100-200"  
  15. queue-capacity="500" rejection-policy="CALLER_RUNS" />  
  16. <task:annotation-driven executor="executor"  
  17. scheduler="scheduler" />  
  18. </beans>  

 

同时,如果想使用注解开发

配置类加上@EnableAsync即可,本质上都是创建AsyncAnnotationBeanPostProcessor对象,另外如果要自定义excutor和exceptionHandller,可以参考@EnableAsync源码

注释:

 

[java]  view plain  copy
 
  1. /**  
  2.  * Enables Spring's asynchronous method execution capability, similar to functionality  
  3.  * found in Spring's {@code <task:*>} XML namespace.  
  4.  *  
  5.  * <p>To be used on @{@link Configuration} classes as follows, where {@code MyAsyncBean}  
  6.  * is a user-defined type with one or more methods annotated with either Spring's  
  7.  * {@code @Async} annotation, the EJB 3.1 {@code @javax.ejb.Asynchronous} annotation,  
  8.  * or any custom annotation specified via the {@link #annotation} attribute.  
  9.  *  
  10.  * <pre class="code">  
  11.  * @Configuration  
  12.  * @EnableAsync  
  13.  * public class AppConfig {  
  14.  *  
  15.  *     @Bean  
  16.  *     public MyAsyncBean asyncBean() {  
  17.  *         return new MyAsyncBean();  
  18.  *     }  
  19.  * }</pre>  
  20.  *  
  21.  * <p>The {@link #mode} attribute controls how advice is applied; if the mode is  
  22.  * {@link AdviceMode#PROXY} (the default), then the other attributes control the behavior  
  23.  * of the proxying.  
  24.  *  
  25.  * <p>Note that if the {@linkplain #mode} is set to {@link AdviceMode#ASPECTJ}, then the  
  26.  * value of the {@link #proxyTargetClass} attribute will be ignored. Note also that in  
  27.  * this case the {@code spring-aspects} module JAR must be present on the classpath.  
  28.  *  
  29.  * <p>By default, Spring will be searching for an associated thread pool definition:  
  30.  * either a unique {@link org.springframework.core.task.TaskExecutor} bean in the context,  
  31.  * or an {@link java.util.concurrent.Executor} bean named "taskExecutor" otherwise. If  
  32.  * neither of the two is resolvable, a {@link org.springframework.core.task.SimpleAsyncTaskExecutor}  
  33.  * will be used to process async method invocations. Besides, annotated methods having a  
  34.  * {@code voidreturn type cannot transmit any exception back to the caller. By default,  
  35.  * such uncaught exceptions are only logged.  
  36.  *  
  37.  * <p>To customize all this, implement {@link AsyncConfigurer} and provide:  
  38.  * <ul>  
  39.  * <li>your own {@link java.util.concurrent.Executor Executor} through the  
  40.  * {@link AsyncConfigurer#getAsyncExecutor getAsyncExecutor()} method, and</li>  
  41.  * <li>your own {@link org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler  
  42.  * AsyncUncaughtExceptionHandler} through the {@link AsyncConfigurer#getAsyncUncaughtExceptionHandler  
  43.  * getAsyncUncaughtExceptionHandler()}  
  44.  * method.</li>  
  45.  * </ul>  
  46.  *  
  47.  * <pre class="code">  
  48.  * @Configuration  
  49.  * @EnableAsync  
  50.  * public class AppConfig implements AsyncConfigurer {  
  51.  *  
  52.  *     @Bean  
  53.  *     public MyAsyncBean asyncBean() {  
  54.  *         return new MyAsyncBean();  
  55.  *     }  
  56.  *  
  57.  *     @Override  
  58.  *     public Executor getAsyncExecutor() {  
  59.  *         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();  
  60.  *         executor.setCorePoolSize(7);  
  61.  *         executor.setMaxPoolSize(42);  
  62.  *         executor.setQueueCapacity(11);  
  63.  *         executor.setThreadNamePrefix("MyExecutor-");  
  64.  *         executor.initialize();  
  65.  *         return executor;  
  66.  *     }  
  67.  *  
  68.  *     @Override  
  69.  *     public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {  
  70.  *         return MyAsyncUncaughtExceptionHandler();  
  71.  *     }  
  72.  * }</pre>  
  73.  *  
  74.  * <p>If only one item needs to be customized, {@code null} can be returned to  
  75.  * keep the default settings. Consider also extending from {@link AsyncConfigurerSupport}  
  76.  * when possible.  
  77.  *  
  78.  * <p>Note: In the above example the {@code ThreadPoolTaskExecutor} is not a fully managed  
  79.  * Spring bean. Add the {@code @Bean} annotation to the {@code getAsyncExecutor()} method  
  80.  * if you want a fully managed bean. In such circumstances it is no longer necessary to  
  81.  * manually call the {@code executor.initialize()} method as this will be invoked  
  82.  * automatically when the bean is initialized.  
  83.  *  
  84.  * <p>For reference, the example above can be compared to the following Spring XML  
  85.  * configuration:  
  86.  *  
  87.  * <pre class="code">  
  88.  * {@code  
  89.  * <beans>  
  90.  *  
  91.  *     <task:annotation-driven executor="myExecutor" exception-handler="exceptionHandler"/>  
  92.  *  
  93.  *     <task:executor id="myExecutor" pool-size="7-42" queue-capacity="11"/>  
  94.  *  
  95.  *     <bean id="asyncBean" class="com.foo.MyAsyncBean"/>  
  96.  *  
  97.  *     <bean id="exceptionHandler" class="com.foo.MyAsyncUncaughtExceptionHandler"/>  
  98.  *  
  99.  * </beans>  
  100.  * }</pre>  





 

 

 

参考:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html

 

 

执行结果:

 

 
 
 

图片无法显示:睡眠之前的2秒打印一次,睡眠之后的22秒打印一次

猜你喜欢

转载自rejoicefromjesus.iteye.com/blog/2404862
今日推荐