spring线程池注解
很多同学在进行编程学习时缺乏系统学习的资料。本页面基于spring线程池注解内容,从基础理论到综合实战,通过实用的知识类文章,标准的编程教程,丰富的视频课程,为您在spring线程池注解相关知识领域提供全面立体的资料补充。同时还包含 safari浏览器、samba、SAMP 的知识内容,欢迎查阅!
spring线程池注解相关知识
-
Spring Boot 中的线程池和 Timer 定时器Spring Boot 是一个只写几个配置,就可以完成很多功能的 Java 框架,例如你想要一个线程池,只需两步: 在应用入口 Application 主类上加注解 @EnableScheduling @SpringBootApplication @EnableScheduling public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } 添加一个线程池配置类,增加 @EnableAsync 注解 @Configuration @EnableAsync public class AsyncConfig { @Value
-
Java 线程池详解构造一个线程池为什么需要几个参数?如果避免线程池出现OOM?Runnable和Callable的区别是什么?本文将对这些问题一一解答,同时还将给出使用线程池的常见场景和代码片段。基础知识Executors创建线程池Java中创建线程池很简单,只需要调用Executors中相应的便捷方法即可,比如Executors.newFixedThreadPool(int nThreads),但是便捷不仅隐藏了复杂性,也为我们埋下了潜在的隐患(OOM,线程耗尽)。Executors创建线程池便捷方法列表:方法名功能newFixedThreadPool(int nThreads)创建固定大小的线程池newSingleThreadExecutor()创建只有一个线程的线程池newCachedThreadPool()创建一个不限线程数上限的线程池,任何提交的任务都将立即执行小程序使用这些快捷方法没什么问题,对于服务端需要长期运行的程序,创建线程池应该直接使用ThreadPoolExecutor的构造方法。没错,上述Execut
-
Java线程池详解构造一个线程池为什么需要几个参数?如果避免线程池出现OOM?Runnable和Callable的区别是什么?本文将对这些问题一一解答,同时还将给出使用线程池的常见场景和代码片段。基础知识Executors创建线程池Java中创建线程池很简单,只需要调用Executors中相应的便捷方法即可,比如Executors.newFixedThreadPool(int nThreads),但是便捷不仅隐藏了复杂性,也为我们埋下了潜在的隐患(OOM,线程耗尽)。Executors创建线程池便捷方法列表:方法名功能newFixedThreadPool(int nThreads)创建固定大小的线程池newSingleThreadExecutor()创建只有一个线程的线程池newCachedThreadPool()创建一个不限线程数上限的线程池,任何提交的任务都将立即执行小程序使用这些快捷方法没什么问题,对于服务端需要长期运行的程序,创建线程池应该直接使用ThreadPoolExecutor的构造方法。没错,上述Execut
-
多线程2,线程池深入理解### 目录介绍- **1.ThreadPoolExecutor类介绍**- 1.1 构造函数- 1.2 参数解析- 1.3 遵循的规则- 1.4 使用线程池管理线程的优点- **2.关于线程池的分类**- 2.1 FixedThreadPool- 2.2 CachedThreadPool- 2.3 ScheduledThreadPool- 2.4 SingleThreadExecutor- **3.线程池一般用法**- 3.1 一般方法介绍- 3.2 newFixedThreadPool的使用- 3.3 newSingleThreadExecutor的使用- 3.4 newCachedThreadPool的使用- 3.5 newScheduledThreadPool的使用- 3.6 线程创建规则- **4.线程池封装**- 4.1 具体可以参考下篇文章- 4.2 参考博客### 前言介绍- **关于线程池关联博客有:**- [多线程1,线程基础知识](http://www.jcodecraeer.com/
spring线程池注解相关课程
spring线程池注解相关教程
- 2.3 线程池 假设您要处理数百个项目,为每个项目启动一个线程将破坏您的系统资源。它看起来像这样:pages_to_crawl = %w( index about contact ... )pages_to_crawl.each do |page| Thread.new { puts page }end如果这样做,您将与服务器启动数百个连接,因此这可能不是一个好主意。一种解决方案是使用线程池。线程池使您可以在任何给定时间控制活动线程的数量。您可以建立自己的池,但是我不建议你这样去做,Ruby有一个Gem可以为您完成这个操作。实例:require 'celluloid'class Worker include Celluloid def process_page(url) puts url endendpages_to_crawl = %w( index about contact products ... )worker_pool = Worker.pool(size: 5)# If you need to collect the return values check out 'futures'pages_to_crawl.each do |page| worker_pool.process_page(page)end这次只有5个线程在运行,完成后他们将选择下一个项目。
- 3.3 线程池配置模块详解 参数名称:coreSize参数说明:该属性用来设置核心线程池的大小,默认为 10 。参数名称:maximumSize参数说明:该属性是用来设置线程池的最大线程数量,默认为 10 ,在 1.5.9 版本之前,线程池的核心线程数量总是与线程池的最大线程数量保持一致。参数名称:allowMaximumSizeToDivergeFromCoreSize参数说明:该属性是用来设置,是否启用 maximumSize ,即设置线程池的 coreSize 和 maximumSize 的值不一致,当被设置为 true 时,该属性生效,即线程池的最大线程数量大于或等于线程池的核心线程数量。该属性的默认值为 false 。参数名称:keepAliveTimeMinutes参数说明:该参数是用来设置线程的存活时间,即在线程池的核心线程数量小于线程池的最大线程数量时,一个线程的可运行时长。该属性的默认值为 1 分钟。
- 3.1 线程池隔离实现服务资源隔离 通过对处理项目中的工作线程的隔离,来避免工作线程处理接口时所产生的阻塞行为,从而保证工作线程可以顺利地调用接口来满足业务需要。而隔离工作线程的方式,就是为每个接口分配一个线程池,并在线程池中维护一定数量的线程,这样,当上述的接口 2 发生服务资源等待时,由于每个接口都分配了不同的线程池,所以不会影响到后续的 3 4 5 接口,如下图所示:线程池隔离实现原理可以看到,由于为每个服务接口均分配了不同的线程池,所以在接口 2 出现服务等待时,并不会影响后续接口的调用,从而保证了业务的顺利进行。我们继续以 hello 方法为例,来看如何实现线程池隔离。@RequestMapping(value = "hello", method = RequestMethod.GET)@HystrixCommand(threadPoolKey = "HelloHystrix", threadPoolProperties = { @HystrixProperty(name = "coresize", value = "2"), @HystrixProperty(name = "allowMaximumSizeToDivergeFromCoreSize", value = "true"), @HystrixProperty(name = "maximumSize", value = "2"), @HystrixProperty(name = "maxQueueSize", value = "2")})@ResponseBodypublic String hello() throws InterruptedException { return "helloWorld";}代码解释:第 2 行,我们通过配置 HystrixCommand 注解的 threadPoolKey 属性来为本接口分配一个名称为 HelloHystrix 的线程池。第 3 行,我们通过配置 threadPoolProperties 中的参数属性,来维护 HelloHystrix 线程池中的核心线程数量、最大线程数量。通过添加上述注解并配置其中的属性,我们就可以通过线程池隔离的方式来实现服务资源隔离。Tips: 线程池中的线程数量,一定要根据该接口所实现的业务需求来设置,设置过多,则会浪费资源空间,设置过少,则不能支撑业务需要,所以配置线程数量一定要谨慎。
- 3. 线程池模型 线程池模型的结构如下:从图中可以看出,线程池模型的程序结构如下:创建一个监听线程,通常会采用 Java 主线程作为监听线程。创建一个 java.net.ServerSocket 实例,调用它的 accept 方法等待客户端的连接。服务器预先创建一组线程,叫做线程池。线程池中的线程,在服务运行过程中,一直运行,不会退出。当有新的客户端和服务器建立连接,accept 方法会返回 java.net.Socket 对象,表示新的连接。服务器一般会创建一个处理 java.net.Socket 逻辑的任务,并且将此任务投递给线程池去处理。然后,监听线程返回,继续调用 accept 方法,等待新的客户端连接。线程池调度空闲的线程去处理任务。在新新任务中调用 java.net.Socket 的 recv 和 send 方法和客户端进行数据收发。当数据收发完成后,调用 java.net.Socket 的 close 方法关闭连接,任务完成。线程重新回归线程池,等待调度。下来,我们同样通过示例代码演示一下线程池模型的编写方法。程序功能和每线程模型完全一致,所以我们只编写服务端程序,客户端程序采用每线程模型的客户端。示例代码如下:import java.io.*;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class TCPServerThreadPool{ // 服务监听端口号 private static final int PORT =56002; // 开启线程数 private static final int THREAD_NUMS = 20; private static ExecutorService pool = null; // 创建一个 socket Task 类,处理数据收发 private static class SockTask implements Callable<Void> { private Socket sock = null; public SockTask(Socket sock){ this.sock = sock; } @Override public Void call() throws Exception { try { while (true){ // 读取客户端数据 DataInputStream in = new DataInputStream( new BufferedInputStream(sock.getInputStream())); int msgLen = in.readInt(); byte[] inMessage = new byte[msgLen]; in.read(inMessage); System.out.println("Recv from client:" + new String(inMessage) + "length:" + msgLen); // 向客户端发送数据 String rsp = "Hello Client!\n"; DataOutputStream out = new DataOutputStream( new BufferedOutputStream(sock.getOutputStream())); out.writeInt(rsp.getBytes().length); out.write(rsp.getBytes()); out.flush(); System.out.println("Send to client:" + rsp + " length:" + rsp.getBytes().length); } } catch (IOException e) { e.printStackTrace(); } finally { if (sock != null){ try { sock.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } } public static void main(String[] args) { ServerSocket ss = null; try { pool = Executors.newFixedThreadPool(THREAD_NUMS); // 创建一个服务器 Socket ss = new ServerSocket(PORT); while (true){ // 监听新的连接请求 Socket conn = ss.accept(); System.out.println("Accept a new connection:" + conn.getRemoteSocketAddress().toString()); pool.submit(new SockTask(conn)); } } catch (IOException e) { e.printStackTrace(); } finally { if (ss != null){ try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } }}
- 3.3 HystrixCommand 注解详解 @HystrixCommand 注解,是 Hystrix 注解中的核心注解,可以说,只要想使用 Hystrix 的功能特性,就必须要使用该注解。@HystrixCommand 注解提供了丰富的属性,来让我们配置 Hystrix 的功能特性,我将经常用到的属性汇总成了一个表格,如下表所示:我们在了解了这些属性之后,就可以使用 HystrixCommand 属性来配置 Hystrix 的功能特性了。属性名称属性类型默认值作用fallbackMethodString空字符串配置服务容错机制defaultFallbackString空字符串配置默认服务容错机制threadPoolKeyString空字符串配置线程池隔离策略threadPoolPropertiesHystrixProperty[]空数组配置线程池详细策略接下来,我们来看看这几个属性的详细信息fallbackMethod 属性该属性的作用就是配置项目中,服务的容错机制(什么是容错机制已在前面文章中有所介绍,这里不再赘述),我们直接看用法。这里以一个简单的 helloWorld 请求为例,我们先来看正常请求。@RequestMapping(value = "hello", method = RequestMethod.GET)@ResponseBodypublic String hello() { return "helloWorld";}代码解释:第 1-2 行,我们使用 SpringBoot 中的注解,将请求暴露出去,即添加 helloWorld 请求的路径。第 3-5 行,我们编写代码,实现 helloWorld 请求,其请求的响应结果是返回 helloWorld 字符串。以上代码中,我们没有添加任何 Hystrix 的注解,只是一个很普通的正常请求,我们先来看下返回结结果。请求返回结果可以看到,请求已经正常返回了 helloWorld 。接下来,让我们模拟以下请求错误的情况,即在请求时,我们认为设置一个延时时间,来让 Hystrix 捕捉到这一异常,并应用 Hystrix 的容错机制。@RequestMapping(value = "hello", method = RequestMethod.GET)@ResponseBody@HystrixCommand(fallbackMethod = "helloFail")public String hello() throws InterruptedException { Thread.sleep(1000); return "helloWorld";}public String helloFail(){ return "helloFailed";}代码解释:第 3 行,我们使用 HystrixCommand 注解的 fallbackMethod 属性来定义当请求不能正常响应时的应急方案,fallbackMethod 属性的值就是请求不能正常响应时,所返回的方法,这里的 helloFail 就是方法名。第 5 行,我们手动加入了一个延时时间,该延时时间可以在响应请求时,延迟一秒响应,这就是我们手动实现的一个服务异常情况,该情况会被 Hystrix 的容错机制捕捉到。第 9-11 行,我们编写代码,实现了一个当请求 helloWorld 失败时,所返回的应急方法,该方法返回 helloFailed 字符串。以上代码中,我们加入了 Hystrix 的容错机制,让我们来看看效果。请求响应失败从上图中我们可以看到,我们还是请求的 helloWorld 请求,但是返回的确是 helloFailed ,这就表明,我们通过 HystrixCommand 注解的 fallbackMethod 属性来配置的服务容错起作用了。defaultFallback 属性defaultFallback 属性和 fallbackMethod 属性所实现的功能是基本相同的,只不过 defaultFallback 属性是用来配置默认的应急方法,即当我们的项目中存在多个应急方法时,我们给其中一个请求所配置的默认应急方法。defaultFallback 属性所实现的效果和 fallbackMethod 属性是相同的,这里不再赘述。threadPoolKey 和 threadPoolProperties属性threadPoolKey 属性是用来配置线程池隔离策略的属性。threadPoolProperties 属性,则是用来配置线程池详细策略的属性,例如,核心线程数量、最大线程数量等。@RequestMapping(value = "hello", method = RequestMethod.GET)@ResponseBody@HystrixCommand(fallbackMethod = "helloFail", threadPoolKey = "HelloHystrix")public String hello() throws InterruptedException { Thread.sleep(1000); return "helloWorld";}public String helloFail(){ return "helloFailed";}第 3 行,我们使用 HystrixCommand 的 threadPoolKey 属性来配置线程池隔离,即我们将 helloWorld 请求划到了名为 HelloHystrix 的线程池下,这样就和主线程分离开了。我们来看一下 threadPoolProperties 属性的具体用法。@RequestMapping(value = "hello", method = RequestMethod.GET)@ResponseBody@HystrixCommand(fallbackMethod = "helloFail", threadPoolProperties = { @HystrixProperty(name = "coresize", value = "2"), @HystrixProperty(name = "allowMaximumSizeToDivergeFromCoreSize", value = "true"), @HystrixProperty(name = "maximumSize", value = "2")})public String hello() throws InterruptedException { Thread.sleep(1000); return "helloWorld";}public String helloFail(){ return "helloFailed";}代码解释:第 4 行,我们为 threadPoolProperties 定义了几个常用的线程池隔离策略,它们分别是:核心线程数、开启最大线程数、最大线程数。至于还有哪些其他的配置项,由于不再本套课程内,同学们可以自行查阅资料了解。Tips: 1. 在实际工作中,defaultFallback 属性相对而言很少会用到,一般会手动使用 fallbackMethod 属性来直接指定相关请求所对应的应急方法; 2. threadPoolProperties 属性经常使用,这里只是将最经常使用的几个配置策略给同学们做了介绍,剩下不常用的希望同学们可以自行查阅了解; 3. 在使用 threadPoolProperties 属性时,如果我们的核心线程数量和最大线程数量相等,此时又有超过该数量的请求来请求服务了,那么,在这种情况下,请一定要配置 Hystrix 的降级策略,否则,后台服务会直接报错。
- 4. 主从多线程模型 架构图分析:主要分为三个模块,分别为 Reactor 主线程、Reactor 子线程、Worker 线程池。其中 Reactor 主线程可以对应多个 Reactor 子线程,也就是说,一个 MainReactor 对应多个 SubReactor;Reactor 主线程的 MainReactor 对象通过 select 监听客户端连接事件,收到事件之后,通过 Acceptor 处理连接事件;当 Acceptor 处理连接事件之后,MainReactor 将连接事件分配给 Reactor 子线程的 SubReactor 进行处理;SubReactor 将连接加入到连接队列进行监听,并且创建 Handler 处理对应的事件。一旦有新的事件(非连接)则分配给 Handler 进行处理;Handler 通过 read () 方法读取数据,并且分发给 Worker 线程池去做业务处理;Worker 线程池分配线程去处理业务,处理完成之后把结果返回给 Handler;Handler 收到 Worker 线程返回的结果之后,再通过 send () 方法返回给客户端。方案的优点:责任明确,单一功能拆分的更细,Reactor 主线程负责接收请求,不负责处理请求;Reactor 子线程负责处理请求。并发量很高的情况,可以减轻单个 Reactor 的压力,并且提高处理速度;Reactor 子线程只负责读取数据和响应数据,耗时的业务处理则丢给 Worker 线程池去处理。这种通过把完整任务层层分发下去,每个组件需要处理的内容就会变的很简单,处理起来效率自然会很高。方案的缺点:编程复杂度非常的高;即使一个 Reactor 主线程对应多个 Reactor 子线程,Reactor 主线程还是会存在单节点故障问题,不过真实业务场景当中,如果考虑单节点故障问题的话,一般都是通过分布式集群(Netty 集群)的方式去解决,而不是靠单节点的线程模型去解决,这里大家了解一下即可。总的来说,主从多线程模型是应用比较多的一种线程模型,包括 Nginx 主从 Reactor 多线程模型、Memcached 主从多线程模型、Netty 主从多线程模型等知名开源框架的。
spring线程池注解相关搜索
-
s line
safari浏览器
samba
SAMP
samplerate
sandbox
sanitize
saper
sas
sass
save
smarty模板
smil
smtp
snapshot
snd
snmptrap
soap
soapclient
soap协议