spring线程模型
很多同学在进行编程学习时缺乏系统学习的资料。本页面基于spring线程模型内容,从基础理论到综合实战,通过实用的知识类文章,标准的编程教程,丰富的视频课程,为您在spring线程模型相关知识领域提供全面立体的资料补充。同时还包含 safari浏览器、samba、SAMP 的知识内容,欢迎查阅!
spring线程模型相关知识
-
Netty 线程模型详解作者: 一字马胡 转载标志 【2017-11-03】更新日志日期更新内容备注2017-11-03添加转载标志持续更新导入在文章Netty线程模型及EventLoop详解中,已经初步分析了Netty中的线程模型以及NioEventLoop的具体实现,在分析Netty线程模型之前还分析了Reactor的多个线程模型,那篇文章的定位在于通过阅读文章,可以对线程模型有一个很好的认识,并且对Netty的线程模型也有一个初步的认识,可以说,掌握了Netty的线程模型,就相当于掌握了Netty的一大部分内容,在我看来,线程模型就是框架的指导思想,在进行其他部分的分析之前,应该首先对线程模型进行分析总结,等了解了框架的线程模型是如何的,接下来的分析就可以基于线程模型来进行,如果在不理解线程模型之前就对框架进行分析,未免会太过盲目,并且也是没有意义的,因为有可能框架整个就是单线程模型的,也可能是多线程模型的,还有可能是更为复杂的线程模型,对于Netty来说,它的线程模型的设计使得他的其他部分的设计更为安全可靠,并
-
NodeJS架构 - 单线程事件循环模型这篇译章探究了NodeJS的架构和单线程事件循环模型。我们将在本文中讨论“NodeJS如何在底层工作,它遵循什么类型的处理模型,NodeJS如何使用单线程模型处理并发请求”等内容。 NodeJS 单线程事件循环模型 正如我们刚才说的,NodeJS使用的是“单线程事件循环模型”的架构去处理多个并发的客户端请求的。 有许多Web应用程序技术,如JSP,Spring MVC,ASP.NET等。但所有这些技术都遵循“多线程请求 - 响应”架构来处理多个并发客户端。 我们已经熟悉“多线程请求 - 响应”架构,因为它被大
-
Dubbo 线程池模型前言 大家好,今天开始给大家分享 — Dubbo 专题之 Dubbo 线程池模型。在前面上个章节中我们讨论了 Dubbo SPI,了解了 Dubbo SPI 其本质是从 JDK 标准的 SPI (Service Provider Interface) 扩展点发现机制加强而来,同时解决了 Java 中 SPI 的一些缺陷。以及我们使用 Dubbo SPI 实现自定义能力的拓展。那本章节我们要讨论的 Dubbo 线程模型也是基于 SPI 实现,那什么是线程模型呢?以及其在我们的项目中有什么作用呢?那么我们在本章节中进行讨论。下面就让我们快
-
Spring的统一事务模型组内每周都有技术分享,轮着来,人人有份。刚来一个月不到,就轮到我了。看了一个星期的Spring事务,分享之,反响还不错。遂将屁屁踢改成文稿,和诸君共食。难度一般,老少咸宜。Spring事务的知识体系进入主题之前,先来了解一下Spring事务,都有哪些内容:Spring事务包含对分布式事务和单机事务的支持,我们用的比较多的是单机事务,也就是只操作一个数据库的事务。单机事务,按照用法分,又可以分为编程式事务模型(TransactionTemplate)和声明式事务模型(@Transactional注解),后者可以理解为 aop + 编程式事务模型。编程式事务模型里面涉及到很多知识点,比如统一事务模型、事务传播级别、事务隔离级别等。我们今天要讲的是其中一点,统一事务模型。希望这次的分享能够让大家,对Spring事务有一个整体性的认识。不仅仅是TemplateSpring的统一事务模型,解决的一个核心问题,就是不管你用的是什么数据访问方式,Hibernate、MyBatis抑或是JDBC,你的Service层的代码
spring线程模型相关课程
spring线程模型相关教程
- 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. 每线程模型 下图展示了每线程模型的结构。从图中可以看出,每线程模型的程序结构如下:创建一个监听线程,通常会采用 Java 主线程作为监听线程。创建一个 java.net.ServerSocket 实例,调用它的 accept 方法等待客户端的连接。当有新的客户端和服务器建立连接,accept 方法会返回,创建一个新的线程和客户端通信。此时监听线程返回,继续调用 accept 方法,等待新的客户端连接。在新线程中调用 java.net.Socket 的 recv 和 send 方法和客户端进行数据收发。当数据收发完成后,调用 java.net.Socket 的 close 方法关闭连接,同时线程退出。下来,我们通过一个简单的示例程序演示一下每线程模型服务器的编写方法。示例程序的基本功能如下:客户端每隔 1 秒向服务器发送一个消息。服务器收到客户端的消息后,向客户端发送一个响应消息。客户端发送完 10 个消息后,关闭 Socket 连接,程序退出。服务器检测到客户端关闭连接后,同样关闭 Socket 连接,并且负责和客户端通信的线程也退出。客户端代码:import java.io.*;import java.net.InetSocketAddress;import java.net.Socket;import java.net.SocketAddress;public class TCPClientMultiThread { // 服务器监听的端口号 private static final int PORT = 56002; // 连接超时时间 private static final int TIMEOUT = 15000; // 客户端执行次数 private static final int TEST_TIMES = 10; public static void main(String[] args) { Socket client = null; try { // 测试次数 int testCount = 0; // 调用无参构造方法 client = new Socket(); // 构造服务器地址结构 SocketAddress serverAddr = new InetSocketAddress("192.168.0.101", PORT); // 连接服务器,超时时间是 15 毫秒 client.connect(serverAddr, TIMEOUT); System.out.println("Client start:" + client.getLocalSocketAddress().toString()); while (true) { // 向服务器发送数据 DataOutputStream out = new DataOutputStream( new BufferedOutputStream(client.getOutputStream())); String req = "Hello Server!"; out.writeInt(req.getBytes().length); out.write(req.getBytes()); // 不能忘记 flush 方法的调用 out.flush(); System.out.println("Send to server:" + req); // 接收服务器的数据 DataInputStream in = new DataInputStream( new BufferedInputStream(client.getInputStream())); int msgLen = in.readInt(); byte[] inMessage = new byte[msgLen]; in.read(inMessage); System.out.println("Recv from server:" + new String(inMessage)); // 如果执行次数已经达到上限,结束测试。 if (++testCount >= TEST_TIMES) { break; } // 等待 1 秒然后再执行 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); } finally { if (client != null){ try { client.close(); } catch (IOException e) { e.printStackTrace(); } } } }}服务器代码:import java.io.*;import java.net.ServerSocket;import java.net.Socket;public class TCPServerPerThread implements Runnable{ private static final int PORT =56002; private Socket sock = null; TCPServerPerThread(Socket sock){ this.sock = sock; } @Override public void run() { // 读取客户端数据 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(); } } } } public static void main(String[] args) { ServerSocket ss = null; try { // 创建一个服务器 Socket ss = new ServerSocket(PORT); while (true){ // 监听新的连接请求 Socket conn = ss.accept(); System.out.println("Accept a new connection:" + conn.getRemoteSocketAddress().toString()); Thread t = new Thread(new TCPServerPerThread(conn)); t.start(); } } catch (IOException e) { e.printStackTrace(); } finally { if (ss != null){ try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } }}客户端采用单线程模型。服务器采用每线程模型,我们采用实现 Runnable 接口的方式实现多线程逻辑。从示例代码可以看出,每线程模型的优点就是结构简单,相比单线程模型,也没有增加复杂度。缺点就是针对每个客户端都创建线程,当和客户端通信结束后,线程要退出。频繁的创建、销毁线程,对系统的资源消耗比较大,只能用在简单的业务场景下。
- 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 如果一旦出现故障,那么整个通讯就会故障。通过以上的分析,其实也是不推荐使用这种模式,除非客户端数量比较少,类似局域网内部的项目,但是我们还是需要了解整个模型是如何演变过来的,而不是一上来就讲解最好的那个方案。只有把整个演变过程了解了,我们才能更好的了解整个线程模型可能存在的性能瓶颈在哪里。
- 5. 模型对比 Reactor 模型和传统的 IO 模型对比传统 IO 模型 Reactor 模型线程分配为每个客户端都分配独立的线程,该线程负责全部的工作(包括:监听、读取、处理、响应)统一的监听客户端请求,并且把功能细分,并且分配给不同的子线程去处理堵塞点在每个子线程的 read () 方法进行堵塞只在 select () 堵塞,select () 是所有客户端共用的入口点整体性能并发量相对有限可以处理高并发Reactor 的整体优点如下:性能好,Reactor 本身虽然是同步的,但是是非堵塞的,可以快速的响应;扩展性好,可以根据 CPU 的核数来调整 Reactor 的实例个数,充分的利用 CPU 资源;复用性好,它是一种思想,可以灵活的运用到不同的中间件、底层框架上。三种 Reactor 线程模型对比单 Reactor 单线程单 Reactor 多线程主从多线程功能一个线程负责所有业务一个线程服务监听、事件处理、转发,多个线程负责逻辑处理一个线程负责监听,多个线程负责事件处理、转发,多个线程负责逻辑处理线程一个线程一个线程,一个线程组一个线程,两个线程组性能低中高高可用否否是
- 1. 进程模型 Nginx 的进程模型前面已经提到过,它是通过异步的、非阻塞的、事件驱动的方式实现的。 Nginx 的工作进程是多进程的,每个 Worker 进程可以异步处理大量的用户请求,因此在高并发下 Nginx 能保持低资源低消耗高性能。Apache 有一共有三种稳定的 MPM(Multi-Processing Module,多进程处理模块)模式,其中最常用和默认的是 prefork 模式。prefork 是一个非线程型的、预派生的 MPM,使用多个进程,每个进程在某个确定的时间只单独处理一个连接,效率高,但内存使用比较大。一个进程相对占用更多的系统资源,消耗更多的内存。因此,Apache 并不擅长处理高并发请求。 在这种场景下,它会将请求放进队列中,一直等到有可用进程,请求才会被处理。因此 Apache 是阻塞型的。当用户请求过多时,开启的进程较多,占用内存大,每秒最多的并发连接请求最多不超过 3000 个,而 Nginx 则可以每秒并发连接超过 10 万请求。
spring线程模型相关搜索
-
s line
safari浏览器
samba
SAMP
samplerate
sandbox
sanitize
saper
sas
sass
save
smarty模板
smil
smtp
snapshot
snd
snmptrap
soap
soapclient
soap协议