spring中异步方法的配置

1、把方法放在一个单独的service类中,用@Async标注方法,用@EnableAsync标注类。也可以用@Async标注service类。

这个时候,这个方法就是异步方法了,调用时会异步执行。但是,每执行一次这个方法都要生成一个线程(线程名以"SimpleAsyncTaskExecutor-"开头),执行完之后线程再销毁。这样很不好,最好有一个线程池,每次方法执行的时候都从线程池中取线程,执行完之后再放回到线程池中。这就有了第2步。

2、在applicationContext.xml中配置一个ExecutorService实例。方法有很多种,以下只是其中一种:

    <bean id="asyncThreadPoolExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="20"/>
<property name="maxPoolSize" value="40"/>
<property name="keepAliveSeconds" value="0"/>
<property name="queueCapacity" value="3000"/>
<property name="threadNamePrefix" value="asyncThreadPool-"/>
</bean>

如果不用上述方法显式地创建线程池,则也可以在applicationContext.xml文件中配置

 <task:executor id="annotationExecutor" pool-size="20-40" queue-capacity="3000" keep-alive="0" rejection-policy="ABORT"/>

这样就会产生一个ThreadPoolTaskExecutor实例。不过这种方式生成的线程池里的线程的名字不能像第一种方法那样自定义,而是固定以"annotationExecutor-"为开头的。

如果配置了多个<task:executor/>,则需要在配置@Async注解的时候,配置其value属性值为某个executorId,这样执行方法时就会使用这个指定的线程池,如@Async(value = "xxx"),否则不会用任何一个线程池,而是每执行一次就创建一个线程。

以上配置针对没有返回值的方法没问题,但是如果异步方法有返回值,而且想要获取该方法的返回值,那么这个异步方法就不能简简单单的返回原来想返回的值类型了,得返回xxxFuture<T>类型。阿里规约插件提醒如下:@Async methods should return void, java.util.concurrent.Future, org.springframework.util.concurrent.ListenableFuture or java.util.concurrent.CompletableFuture。

示例如下:

    @Async(value = "annotationExecutor")
public ListenableFuture<String> print() {
try {
Thread.sleep(3000);
LOGGER.info("async thread: " + Thread.currentThread().getName());
} catch (Exception e) {
LOGGER.error(e);
}
return new AsyncResult<String>("异步返回值");
}

AsyncResult全类名是org.springframework.scheduling.annotation.AsyncResult,实现了ListenableFuture接口。

需要特别提醒下, <task:annotation-driven/>这个跟异步没有半毛钱关系。跟定时任务有点关系,配置了的话,就不用@EnableScheduling注解了。

spring中定时任务的配置

1、用@Scheduled标注方法,用@EnableScheduling标注类,就可以了。

这时现在每执行一次定时任务,就会创建一个线程,执行完后销毁。需要引入线程池。这就需要第2步

2、在applicationContext.xml中配置如下:

    <bean id="scheduledThreadPoolExecutor" class="java.util.concurrent.ScheduledThreadPoolExecutor">
<constructor-arg name="corePoolSize" value="10"/>
<constructor-arg name="threadFactory" ref="threadFactory"/>
</bean>

并新建一个Config类(类名随便),内容如下:

@Configuration
public class Config {
@Bean("threadFactory")
public ThreadFactory getThreadFactory() {
return new ThreadFactoryBuilder().setNameFormat("scheduled-pool-%d").setPriority(10).setDaemon(false).build();
}
}

如果不用上述方法显式创建定时任务线程池,则还可以在applicationContext.xml中配置:

<task:scheduler id="scheduler" pool-size="5"/>

这种方法会生成一个指定大小的org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler实例。不过同样不能自定义线程名,线程名固定以"scheduler-"开头。

实际测试发现,如果既显式配置ScheduledExecutorService实例,又配置<task:scheduler/>的话,定时任务会用<task:scheduler/>对应的线程池。显示配置的ScheduledExecutorService实例没用。

最佳实践:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.google.common.util.concurrent.ThreadFactoryBuilder; @Configuration
public class Config { @Bean("asyncThreadPoolExecutor")
public ExecutorService getThreadPoolExecutor() {
return new ThreadPoolExecutor(20,
40,
0,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3000),
new ThreadFactoryBuilder().setNameFormat("asyncThreadPool-%d").setPriority(10).setDaemon(false).build(),
new ThreadPoolExecutor.AbortPolicy());
} @Bean("scheduledThreadPoolExecutor")
public ScheduledExecutorService getThreadFactory() {
return new ScheduledThreadPoolExecutor(10,
new ThreadFactoryBuilder().setNameFormat("scheduledThreadPool-%d").setPriority(10).setDaemon(false).build(),
new ThreadPoolExecutor.AbortPolicy());
} }

DateUtils时间工具类探究的更多相关文章

  1. DateUtils 时间工具类

    首先,定义`时间枚举值` public enum TimeEnum { /** * 时间格式 */ YYYY_MM_DD("yyyy-MM-dd"), YYYY_MM_DD_HH_ ...

  2. 小记Java时间工具类

    小记Java时间工具类 废话不多说,这里主要记录以下几个工具 两个时间只差(Data) 获取时间的格式 格式化时间 返回String 两个时间只差(String) 获取两个时间之间的日期.月份.年份 ...

  3. java时间工具类

    在项目中,很多地方需要根据时间获取相应的数据,将时间格式化,或者时间比较等相关操作.一个良好的工具类不仅可以减少代码冗余,还能促进业务处理,加快进度. /** * @author: lxw * @Da ...

  4. Apache Commons Lang之日期时间工具类

    码农不识Apache,码尽一生也枉然. FastDateFormat FastDateFormat是一个快速且线程安全的时间操作类,它完全可以替代SimpleDateFromat.因为是线程安全的,所 ...

  5. 时间工具类之"获取相差天数"

    一.时间工具类DateUtils之"获取相差天数" 1 /** 2 * 相差天数 3 * 4 * <p>TODO 方法功能描述 5 * 6 * @param start ...

  6. 代码片段:基于 JDK 8 time包的时间工具类 TimeUtil

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “知识的工作者必须成为自己时间的首席执行官.” 前言 这次泥瓦匠带来的是一个好玩的基于 JDK ...

  7. Java日期工具类,Java时间工具类,Java时间格式化

    Java日期工具类,Java时间工具类,Java时间格式化 >>>>>>>>>>>>>>>>>&g ...

  8. 超详细的Java时间工具类

    package com.td.util; import java.sql.Timestamp; import java.text.ParseException; import java.text.Pa ...

  9. 基于Java8的日期时间工具类DateTimeFormatter

    原文:https://blog.csdn.net/qq_36596145/article/details/85331002 import java.time.Instant; import java. ...

随机推荐

  1. 扯蛋css

    使网页旋转代码: javascript:window.i=1;setInterval(function(){i++;document.body.style.cssText+="-webkit ...

  2. 手动添加PopMenu出现的问题

    最近在github上找了个比较酷的弹出菜单PopMenu用来做分享页面,demo下载运行OK,于是拖进项目中,一编译就呵呵了.... 一看demo目录,原来这还还引用了其他库,于是把pod下面的pop ...

  3. 面试题-Java基础-线程部分

    1.进程和线程的区别是什么? 进程是执行着的应用程序,而线程是进程内部的一个执行序列.一个进程可以有多个线程.线程又叫做轻量级进程. 2.创建线程有几种不同的方式?你喜欢哪一种?为什么? 有三种方式可 ...

  4. Java实现二叉树先序,中序,后序遍历

    以下是我要解析的一个二叉树的模型形状 接下来废话不多直接上代码 一种是用递归的方法,另一种是用堆栈的方法: 首先创建一棵树: public class Node { private int data; ...

  5. eclipse 发布web工程,修改tomcat端口

    如果想修改tomcat发布的端口,有两种方法: 1.用记事本打开tomcat安装目录下的conf文件夹下的server.xml,找到<Connector port="8080" ...

  6. SSLPinning 延伸

    AFSecurityPolicy用于验证HTTPS请求的证书,先来看看HTTPS的原理和证书相关的几个问题. HTTPS HTTPS连接建立过程大致是,客户端和服务端建立一个连接,服务端返回一个证书, ...

  7. Gdiplus 贴图(助记) -------------------拖动整个对话框

    最简单的两种方法: 一.使WM_NCHITTEST始终返回HTCAPTION,也就是欺骗系统让他以为这是菜单栏. LRESULT CDemoDlg::OnNcHitTest(CPoint point) ...

  8. 为Array 添加indexOf

    为array赋予属性 if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (elt /*, from*/) { var ...

  9. 自动安装memcached服务端与PHP扩展Memcached

    该脚本基于阿里云服务器安装脚本,并只能运用于centos / aliyun os,该脚本使用时,需要与阿里云安装脚本的install.sh放在同一目录下.有缘人切忌乱用: #! /bin/bash # ...

  10. zoj 1649 Rescue

    BFS..第一次使用C++ STL的队列来写广搜. #include<stdio.h> #include<string.h> #include<math.h> #i ...