java 线程 交给spring_浅谈Java中spring 线程异步执行

多线程并发处理起来通常比较麻烦,如果你使用spring容器来管理业务bean,事情就好办了多了。spring封装了Java的多线程的实现,你只需要关注于并发事物的流程以及一些并发负载量等特性,具体来说如何使用spring来处理并发事务:

1.了解 TaskExecutor接口

Spring的TaskExecutor接口等同于java.util.concurrent.Executor接口。 实际上,它存在的主要原因是为了在使用线程池的时候,将对Java5的依赖抽象出来。 这个接口只有一个方法execute(Runnable task),它根据线程池的语义和配置,来接受一个执行任务。最初创建TaskExecutor是为了在需要时给其他Spring组件提供一个线程池的抽象。 例如ApplicationEventMulticaster组件、JMS的 AbstractMessageListenerContainer和对Quartz的整合都使用了TaskExecutor抽象来提供线程池。 当然,如果你的bean需要线程池行为,你也可以使用这个抽象层。

2. TaskExecutor接口的实现类

(1)SimpleAsyncTaskExecutor 类

这个实现不重用任何线程,或者说它每次调用都启动一个新线程。但是,它还是支持对并发总数设限,当超过线程并发总数限制时,阻塞新的调用,直到有位置被释放。如果你需要真正的池,请继续往下看。

(2)SyncTaskExecutor类

这个实现不会异步执行。相反,每次调用都在发起调用的线程中执行。它的主要用处是在不需要多线程的时候,比如简单的test case。

(3)ConcurrentTaskExecutor 类

这个实现是对Java 5 java.util.concurrent.Executor类的包装。有另一个备选, ThreadPoolTaskExecutor类,它暴露了Executor的配置参数作为bean属性。很少需要使用ConcurrentTaskExecutor, 但是如果ThreadPoolTaskExecutor不敷所需,ConcurrentTaskExecutor是另外一个备选。

(4)SimpleThreadPoolTaskExecutor 类

这个实现实际上是Quartz的SimpleThreadPool类的子类,它会监听Spring的生命周期回调。当你有线程池,需要在Quartz和非Quartz组件中共用时,这是它的典型用处。

(5)ThreadPoolTaskExecutor 类

它不支持任何对java.util.concurrent包的替换或者下行移植。Doug Lea和Dawid Kurzyniec对java.util.concurrent的实现都采用了不同的包结构,导致它们无法正确运行。 这个实现只能在Java 5环境中使用,但是却是这个环境中最常用的。它暴露的bean properties可以用来配置一个java.util.concurrent.ThreadPoolExecutor,把它包装到一个TaskExecutor中。如果你需要更加先进的类,比如ScheduledThreadPoolExecutor,我们建议你使用ConcurrentTaskExecutor来替代。

(6)TimerTaskExecutor类

这个实现使用一个TimerTask作为其背后的实现。它和SyncTaskExecutor的不同在于,方法调用是在一个独立的线程中进行的,虽然在那个线程中是同步的。

(7)WorkManagerTaskExecutor类

这个实现使用了CommonJ WorkManager作为其底层实现,是在Spring context中配置CommonJ WorkManager应用的最重要的类。和SimpleThreadPoolTaskExecutor类似,这个类实现了WorkManager接口,因此可以直接作为WorkManager使用。

案例

注册TaskExecutor

@Configuration

public class WebMvcConfigurerAdpter extends AbstractWebMvcConfigurerAdpter {

@Override

public void configureMessageConverters(List> converters) {

super.configureMessageConverters(converters);

WafJsonMapper.getMapper().enable(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS);

}

@Bean

public TaskExecutor taskExecutor() {

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

executor.setCorePoolSize(5);

executor.setMaxPoolSize(10);

return executor;

}

}

使用:

@Service

public class TaskService {

@Autowired

private TaskExecutor executor;

public void execute() {

executor.execute(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 10; i++) {

try {

Thread.sleep(1000);

System.out.println("task running ...");

} catch (Exception e) {

}

}

}

});

}

}

@RestController

@RequestMapping(value = "/v0.1")

public class TaskController {

@Autowired

private TaskService taskService;

@RequestMapping()

public Object execute() {

taskService.execute();

Map res = new HashMap();

res.put("result", "success");

return res;

}

}

程序不会等到10个线程都跑完才返回结果,不是阻塞程序,返回结果后,线程仍然在执行。

案例:

ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();

//线程池所使用的缓冲队列

poolTaskExecutor.setQueueCapacity(200);

//线程池维护线程的最少数量

poolTaskExecutor.setCorePoolSize(5);

//线程池维护线程的最大数量

poolTaskExecutor.setMaxPoolSize(1000);

//线程池维护线程所允许的空闲时间

poolTaskExecutor.setKeepAliveSeconds(30000);

poolTaskExecutor.initialize();

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

ThreadPoolTaskExecutor poolTaskExecutor = (ThreadPoolTaskExecutor)ctx.getBean("taskExecutor");

Thread udpThread = new Thread(udp);

poolTaskExecutor.execute(udpThread);

获取当前线程池活动的线程数:

int count = poolTaskExecutor.getActiveCount();

logger.debug("[x] - now threadpool active threads totalNum : " +count);

配置解释

当一个任务通过execute(Runnable)方法欲添加到线程池时:

1、 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

2、 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。

3、如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。

4、 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

5、 当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/505564.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java编程实现素数环_结对编程(JAVA实现)

项目成员&#xff1a;黄思扬(3117004657)、刘嘉媚(3217004685)二、PSP表格PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)Planning计划6040 Estimate 估计这个任务需要多少时间6040Development开发14401505 Analysis 需求分析3015 Design Spec 生成设计文档…

自学java编译老是出错_为什么按照书上的代码,编译老是出错?

老是又小伙伴在群里说我的代码是按照书上的代码敲的&#xff0c;就是编译不过&#xff1f;想不通呀&#xff01;目前市面上的一些书都是十来年以前编写的了&#xff0c;你不幸看的还是这些书&#xff0c;错误原因就在这里。比如谭浩强的C语言程序设计这个本书都出了N版了&#…

java版的中世纪战争_世界战争英雄设置-火焰纹章英雄英雄地图及AI命令设置

英雄地图及AI命令设置游戏中练级塔中的AI设置和故事地图中的一样&#xff0c;所以如果故事地图中的AI是主动出击的&#xff0c;那练级塔一样的地图也是主动出击。故事地图中配置有5个敌人&#xff0c;在练级塔中也一样会配置5个敌人。不同的是职业可能会发生变化&#xff0c;但…

python pip安装依赖的常用软件源

目录 引言 一、什么是镜像源&#xff1f;​​​​​​​ 二、清华源 三、阿里源 四、中科大源 五、豆瓣源 六、更多资源 引言 在软件开发和使用过程中&#xff0c;我们经常需要下载和更新各种软件包和库文件。然而&#xff0c;由于网络环境的限制或者服务器的负载&#…

java虚拟机规范 51cto_java虚拟机

最近学习java虚拟机做了一些整理&#xff0c;会陆续发完。Java虚拟机一、概念&#xff1a;当我们谈到java虚拟机的时候&#xff0c;有可能指下面3个方面&#xff1a;1)&#xff1a;抽象java虚拟机的规范。2)&#xff1a;一个java虚拟机具体的实现。------实现是指&#xff1a;实…

java重定向链接页面变小_java web的进来看一下!页面重定向的异常!帮忙看一下!谢谢了!...

我用login.jsp进行登录留言板的管理页面用一个servlet进行身份验证。成功----->通过request.getRequestDispatcher("/admin/secure/manage?qlist").forward(request, response);return;其中/admin/secure/manage是ManageServlet的映射路径。来登录到manage的管理…

java数组设置结束_Java 数组最佳指南,快收藏让它吃灰

两年前&#xff0c;我甚至写过一篇文章&#xff0c;吐槽数组在 Java 中挺鸡肋的&#xff0c;因为有 List 谁用数组啊&#xff0c;现在想想那时候的自己好幼稚&#xff0c;好可笑。因为我只看到了表面现象&#xff0c;实际上呢&#xff0c;List 的内部仍然是通过数组实现的&…

java窗口只能点一个_java – 为什么界面只能在顶级类中声明?

Won’t inner class become top-level class if I put it into another Class file?不,它仍然是一个内部类,文件名指示(IIRC它是OuterClass $InnerClass.class).内部类可以访问外部类的属性,即它们依赖于它们的外部类’实例.使用界面,您无法做到这一点.想到一个完全不相关的类…

Mysql 中Sql控制流语句_DCL语句/控制流语句

一、(1)DCL(数据控制语言)主要是数据库管理员用来管理其他用户权限时使用的语句&#xff1b;可以授予的权限包括以下&#xff1a;列权限&#xff1a;和表中的一个具体列相关、表权限&#xff1a;和一个具体数据表中的所有数据相关、数据库权限&#xff1a;和一个具体数据库中的…

Java7运行applet_Java applet不会在JRE7下运行,控制台中不会显示错误

在Windows 7,64位下&#xff0c;由于升级到JRE-7 32位&#xff0c;在IE9 32位或Chrome下&#xff0c;我无法运行诸如this one之类的小程序。在Applet矩形内&#xff0c;我看到消息“Error。Click for details”点击applet框(空白)会出现一个对话框&#xff1a;Application Erro…

同包类 和 其他类 java_关于继承:为什么Java中的“protected”修饰符允许访问同一个包中的其他类?...

在Java中&#xff0c;具有"受保护"修饰符的成员不仅可以由同一个类和子类访问&#xff0c;还可以由同一个包中的每个人访问&#xff1f;我想知道语言设计的原因&#xff0c;而不是实际的应用程序(例如&#xff0c;测试)1坦率地说我也想知道为什么。 它总是让我感到震…

java打印已经被加载的类_使用URLClassLoader加载类,不会报错,但被加载类中的内容也没有打印出来...

被加载类和加载类的程序在一个文件夹下&#xff1b;运行没有任何结果&#xff1a;D:java_exercise>javac URLTest.javaD:java_exercise>java URLTestD:java_exercise>加载类&#xff1a;import java.net.*;import java.io.File;import java.net.URLClassLoader ;publi…

python反序列化总结_单例模式的反序列化总结

最近观看effective in java &#xff0c;提到单例模式创建过程中&#xff0c;如果是要保证该对象是可序列化的&#xff0c;需要考虑两点&#xff1a;1、继承Serializable接口2、增加readResolve方法比较疑惑的是为什么需要增加这个方法&#xff0c;在以往的使用中需要被序列化的…

ipv6+ssh+java_IPv6的本地联网地址计算方法详解

IPv6的世界里&#xff0c;如果DHCP6和SLACC这两位大佬都为没有为可怜的网卡分配IP地址&#xff0c;也没有人为网卡设置静态的IP地址&#xff0c;系统就会为网卡计算一个IPv6的网址来。这样的网址只能在本地使用&#xff0c;不得路由&#xff0c;所以&#xff0c;被称为“link-l…

java gzipoutputstream_java – GZIPInputStream逐行读取

我有一个.gz格式的文件。用于读取此文件的java类是GZIPInputStream。但是&#xff0c;此类不会扩展BufferedReader类的java。因此&#xff0c;我无法逐行读取文件。我需要这样的东西reader new MyGZInputStream( some constructor of GZInputStream)reader.readLine()...我虽然…

java互斥锁的实现原理_java-深入分析synchronized原理

互斥锁互斥锁futex&#xff0c;全拼fast userspace mutexes&#xff0c;直翻为快速用户空间互斥器&#xff0c;它是我们上层应用实现锁的最常用方法。futex是一块所有进程都可以访问的内存&#xff0c;是通过cpu的原子操作修改内存中的值来尝试获取琐&#xff0c;如果没有竞争&…

php 自定义加密算法,php自定义加密函数、解密

“/*加密*/function addcoder($str){$yuan abA!c1dB#ef2Cg$h%iD_3jkl^E:m}4n.o{&F*p)5q(G-r[sH]6tuIv7wJxy8z9K0;$jia zAy%0Bx1C$wDv^Eu2-t3(F{sr&G4q_pH5*on6I)m:l7.Jk]j8K}ihgf9#ed!cb[a;if ( strlen($str) 0) return false;for($i 0;$i{for($j 0;$j{if($str[$i…

京东开普勒php接口,IOS菜鸟初学第十五篇:接入京东开普勒sdk,呼起京东app打开任意京东的链接-Go语言中文社区...

我之前写了一篇关于接入京东联盟sdk的文章&#xff0c;但是最近&#xff0c;由于这个原因&#xff0c;如下图导致需要重新集成京东的sdk&#xff0c;但是由于某种原因&#xff0c;因为android和ios端不统一&#xff0c;android接入的是京东开普勒的SDK&#xff0c;这次为了统一…

php用不了for循环吗,php中的这两个for循环有什么区别吗?

如下两个for循环&#xff0c;执行的结果不一样的。for($i 0,$j 0;$i dump($i . - . $j);}echo ;for($i 0;$i dump($i . * . $j);}}结果打印&#xff1a;string(3) "0-0"string(3) "1-1"string(3) "2-2"string(3) "3-3"string(3) &q…

php输出楼层号,ZBlog开发中实现评论楼层号正确输出的具体方法代码

在官方的wiki中&#xff0c;针对评论部分的标签调用是集成了评论楼号的&#xff0c;即标签{$comment.FloorID}。这个标签是不计算子评论的&#xff0c;所以并不是采用key直接计算出的楼号。经过测试&#xff0c;我们会发现&#xff0c;这个楼号存在一定BUG&#xff01;具体表现…