spring多例线程池
很多同学在进行编程学习时缺乏系统学习的资料。本页面基于spring多例线程池内容,从基础理论到综合实战,通过实用的知识类文章,标准的编程教程,丰富的视频课程,为您在spring多例线程池相关知识领域提供全面立体的资料补充。同时还包含 safari浏览器、samba、SAMP 的知识内容,欢迎查阅!
spring多例线程池相关知识
-
多线程3,线程池封装库目录介绍1.遇到的问题和需求1.1 遇到的问题有哪些1.2 遇到的需求1.3 多线程通过实现Runnable弊端1.4 为什么要用线程池2.封装库具有的功能2.1 常用的功能3.封装库的具体使用3.1 一键集成3.2 在application中初始化库3.3 最简单的runnable线程调用方式3.4 最简单的异步回调4.线程池封装思路介绍4.1 自定义Runnable和自定义Callable类4.2 添加回调接口AsyncCallback和ThreadCallback4.3 创建线程池配置文件4.4 创建java平台和android平台消息器Executor4.5 创建PoolThread继承Executor4.6 使用builder模式获取线程池对象4.7 灵活创建线程池[重点]4.8 启动线程池中的任务5.其他介绍5.1 参考的开源案例5.2 参考的博客5.3 我的博客0.前言介绍0.1 基础介绍轻量级线程池封装库,支持线程执行过程中状态回调监测(包含成功,失败,异常等多种状态);支持创建异步任务,并
-
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
-
线程、多线程与线程池总结先看几个概念:线程:进程中负责程序执行的执行单元。一个进程中至少有一个线程。多线程:解决多任务同时执行的需求,合理使用CPU资源。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多线程运行具有不确定性。线程池:基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。如果对线程概念不清晰的话,不妨先看看我是一个线程这篇文章,拟人化的故事阐述线程的工作原理。 线程创建线程的两种方式:一、继承Thread类,扩展线程。class DemoThread extends Thread { @Override public void run() { &
-
多线程之线程池(六)Java中线程池是运用最多的并发框架,几乎所有并发的程序都可以使用线程池来完成。阿里巴巴Java开发手册中明确指出:线程资源必须通过线程池提供,不允许在应用中自行显示创建线程。与文无关在实际的生产环境中,线程的数量必须得到控制,盲目的大量创建线程对系统性能是有伤害的,合理使用线程好处:减少在创建和销毁现场上所消耗的时间和系统资源提高响应速度,无需创建可以直接运行提高线程的可管理性。使用线程池可以进行统一分配,调优和监控,但是要做到合理利用线程池,必须对其原理了如指掌。线程池工作原理当向线程池提交一个任务的时候。先看线程池中的核心线程是否有空闲的,如果有创建一个工作线程来执行任务。如果核心线程都在工作,那么进入下一步判断任务队列是否满了,如果任务队列未满,则把任务存储到任务队列,执行下一步。如果满了,执行拒绝策略。添加到任务队列之后,再判断核心线程是否有空闲的,如果没有空闲的,那么尝试创建新的非核心线程执行任务。 // 线程池处理步骤 public void 
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. 线程池模型 线程池模型的结构如下:从图中可以看出,线程池模型的程序结构如下:创建一个监听线程,通常会采用 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.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.3 线程池配置模块详解 参数名称:coreSize参数说明:该属性用来设置核心线程池的大小,默认为 10 。参数名称:maximumSize参数说明:该属性是用来设置线程池的最大线程数量,默认为 10 ,在 1.5.9 版本之前,线程池的核心线程数量总是与线程池的最大线程数量保持一致。参数名称:allowMaximumSizeToDivergeFromCoreSize参数说明:该属性是用来设置,是否启用 maximumSize ,即设置线程池的 coreSize 和 maximumSize 的值不一致,当被设置为 true 时,该属性生效,即线程池的最大线程数量大于或等于线程池的核心线程数量。该属性的默认值为 false 。参数名称:keepAliveTimeMinutes参数说明:该参数是用来设置线程的存活时间,即在线程池的核心线程数量小于线程池的最大线程数量时,一个线程的可运行时长。该属性的默认值为 1 分钟。
- 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 主从多线程模型等知名开源框架的。
- 3. 单 Reactor 多线程模型 架构图说明:Reactor 通过 Select 监听客户端请求事件,受到事件之后它本身不负责处理,而是把事件转发出去;如果是建立连接请求,则由 Acceptor 进行处理;如果不是建立连接请求,则转发给 Handler 负责处理;Handler 也不负责处理具体的业务,而是通过 read () 方法读取数据,然后再次分发给线程池去进行处理;线程池会分配一个子线程去处理具体的业务,处理完成之后把结果返回给 Handler,并释放连接给连接池。模式的优点:可以充分的利用多核 CPU 的资源,提高处理任务的性能;把业务处理从整个模型中剥离并丢给线程池去处理,避免某个业务处理或者某次业务处理太慢导致其他业务处理受到影响;相比传统 I/O 堵塞模型,如果一旦没有客户端发起请求,那么线程池将不会处于堵塞状态,而是释放并且可以处理其他的业务,对于性能调优来说,最宝贵的就是线程资源,一旦线程资源得不到释放,整个应用将会卡掉。模式的缺点:多线程之间的数据共享和访问比较复杂,比如:Handler 给 Worker 线程分发数据;Reactor 处理所有事件的监听、转发、响应,都是单线程,在高并发的情况下,负责处理业务的 Worker 可能正常,但是 Reactor 就会容易遇到性能瓶颈;Reactor 如果一旦出现故障,那么整个通讯就会故障。通过以上的分析,其实也是不推荐使用这种模式,除非客户端数量比较少,类似局域网内部的项目,但是我们还是需要了解整个模型是如何演变过来的,而不是一上来就讲解最好的那个方案。只有把整个演变过程了解了,我们才能更好的了解整个线程模型可能存在的性能瓶颈在哪里。
spring多例线程池相关搜索
-
s line
safari浏览器
samba
SAMP
samplerate
sandbox
sanitize
saper
sas
sass
save
smarty模板
smil
smtp
snapshot
snd
snmptrap
soap
soapclient
soap协议