vaniglia 源码学习 (六)
学习vaniglia源码中的socket部分,主要针对其server侧的代码实现做个记录。其代码有两部分值得学习,一块是实现了一个经典的线程池,另外一个是利用代理接口扩展业务的具体socket消息处理。
socket的server主要由三个部分组成:
- ServerDelegate接口,提供readRequest、writeResult接口。由用户扩展并注册到SocketReceiver中;
- SocketReceiver类,socket server的工作线程;
- SocketServer类,初始化一个SocketReceiver的线程池,当accept返回时,唤醒空闲的SocketReceiver执行。
SocketServer核心代码主要是两个部分:
一是初始化线程池:
SocketReceiver[] receivers = new SocketReceiver[numOfThreads]; for (int i = 0; i < numOfThreads; i++) { ServerDelegate delegate = null; try { delegate = (ServerDelegate)serverDelegateClass.newInstance(); } catch (InstantiationException e) { //略 } SocketReceiver receiver = SocketReceiver.createSocketReceiver(delegate);//该函数中SocketReceiver线程被start receiversPool.addElement(receiver);//receiversPool是一个vector变量; receivers[i] = receiver; }
二是在accept返回时选择ready的线程执行,如下:
SocketReceiver receiver = (SocketReceiver)receiversPool.get(receiverIndex);//receiverIndex是外侧循环的变量 receiverIndex = (receiverIndex + 1) % receiversPoolSize;//通过index遍历vector if (receiver.isReady()) { handling = true; if (clientSocketSoTimeout > 0) { logger.debug("Setting client socket SoTimeout to "+clientSocketSoTimeout+"ms"); try { clientSocket.setSoTimeout(clientSocketSoTimeout); } catch (SocketException e) { logger.error("Exception while setting SoTimeout for client socket", e); } } clientSocket.setTcpNoDelay(true); receiver.handle(clientSocket);//一个工作线程被唤醒 }
SocketReceiver的核心代码是典型的工作线程,我将它简化成一个框架版本,如下:
public class Receive implements Runnable { private boolean ready; Receive(){ ready = true; } static Receive start(){ Receive rev = new Receive(); Thread t = new Thread(rev); t.start(); return rev; } @Override public void run() { while(true){ synchronized(this){ while(true == ready){//当handler没有调用时该线程wait中。 try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("Receive run, service handler");//这部分的代码在在socket里就是处理input和output,实现时调用业务的代理接口。 ready = true; synchronized(this) { notify(); } } } public synchronized void handler(){//有业务出发时,handler被调用 while(ready == false){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } ready = false; notify(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)