云计算百科
云计算领域专业知识百科平台

你还在用单线程处理请求?这年头还不会写多线程服务器,真的不慌吗?

👋 你好,欢迎来到我的博客!我是【菜鸟不学编程】    我是一个正在奋斗中的职场码农,步入职场多年,正在从“小码农”慢慢成长为有深度、有思考的技术人。在这条不断进阶的路上,我决定记录下自己的学习与成长过程,也希望通过博客结识更多志同道合的朋友。      🛠️ 主要方向包括 Java 基础、Spring 全家桶、数据库优化、项目实战等,也会分享一些踩坑经历与面试复盘,希望能为还在迷茫中的你提供一些参考。   💡 我相信:写作是一种思考的过程,分享是一种进步的方式。       如果你和我一样热爱技术、热爱成长,欢迎关注我,一起交流进步!

全文目录:

    • ❓前言
    • 🧠前置知识你得懂一点,不然真听不懂
    • 🚀实战演示:手写一个多线程的Socket服务端
      • 1️⃣ 服务端代码(支持多客户端并发连接)
      • 2️⃣ 客户端代码(多个客户端你自己开多个就行)
    • 🧩你看懂了吗?这里才是多线程的灵魂
      • 🔍几个关键知识点:
    • 💡延伸一波,带你入点更深的坑
    • ✍️写在最后:代码你可以复制,理解必须原创!
    • 📌总结
    • 📣你还在用单线程服务?真的不考虑提升一下姿势水平?
    • 📝 写在最后

❓前言

唉,说实话,现在做 Java 后端的朋友,如果你还没真正理解多线程服务器的实现机制,我真的是要摇摇头了。你以为 Tomcat 牛,是因为它 logo 好看?还不是背后的线程池机制 + 多路复用模型给力!

今天我不跟你扯那些晦涩难懂的理论,咱们实打实撸个Java 多线程 Socket 服务端实例,从最底层理解多线程服务器的运行机制,看完之后保证你不止知道“怎么用”,更能体会到“为什么这么用”。

🧠前置知识你得懂一点,不然真听不懂

先别急着上代码,我们得先把下面几个概念捋清楚,要不然后面看代码你可能会发出“???”的声音:

  • Socket 编程:Java 网络编程最基础的玩意儿,就是一端监听,另一端请求连接,类似打电话。
  • 线程/多线程:你主线程一个人在干活,那肯定慢啊,多个线程同时响应多个客户端,这才是正解。
  • 阻塞/非阻塞模型:这跟你排队买奶茶一样,阻塞就是“等到买完了才能接下一个”,非阻塞是“多个窗口同时服务”。
  • 线程池(ExecutorService):别一个请求就 new 一个线程,GC 都能把你累死。线程池才是正道。

🚀实战演示:手写一个多线程的Socket服务端

来,废话不多说,直接上干货!

1️⃣ 服务端代码(支持多客户端并发连接)

import java.io.*;
import java.net.*;
import java.util.concurrent.*;

public class MultiThreadedServer {

// 线程池处理客户端连接
private static ExecutorService threadPool = Executors.newFixedThreadPool(10);

public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8888)) {
System.out.println("😎 服务器启动,端口8888,准备接客…");

while (true) {
// 阻塞等待客户端连接
Socket clientSocket = serverSocket.accept();
System.out.println("👉 有客户端连接啦:" + clientSocket.getInetAddress());

// 每个连接交给线程池处理
threadPool.execute(new ClientHandler(clientSocket));
}

} catch (IOException e) {
e.printStackTrace();
}
}

// 客户端处理类
static class ClientHandler implements Runnable {
private Socket socket;

public ClientHandler(Socket socket) {
this.socket = socket;
}

@Override
public void run() {
try (
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
) {
String message;
while ((message = reader.readLine()) != null) {
System.out.println("📨 收到客户端消息:" + message);
writer.write("收到啦,别急!\\n");
writer.flush();
}
} catch (IOException e) {
System.out.println("⚠️ 客户端连接异常:" + e.getMessage());
} finally {
try {
socket.close();
System.out.println("👋 客户端断开连接");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

2️⃣ 客户端代码(多个客户端你自己开多个就行)

import java.io.*;
import java.net.*;

public class SimpleClient {
public static void main(String[] args) {
try (
Socket socket = new Socket("127.0.0.1", 8888);
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
) {
String input;
while ((input = console.readLine()) != null) {
writer.write(input + "\\n");
writer.flush();

String response = reader.readLine();
System.out.println("🙋 服务器回复:" + response);
}

} catch (IOException e) {
e.printStackTrace();
}
}
}

🧩你看懂了吗?这里才是多线程的灵魂

可能你会说,“不就是接个 Socket 然后丢到线程池嘛,这有啥难的?”

这可就是本事啊朋友。真正厉害的服务端不是你能不能“跑起来”,而是你得知道为啥用线程池、怎么防止线程泄露、怎么处理高并发。

🔍几个关键知识点:

  • 为什么用线程池而不是直接 new Thread? 因为频繁创建和销毁线程开销太大,还可能引发OOM(Out of Memory)。线程池能重用线程,而且可以限制最大并发线程数,避免服务器挂掉。

  • 为什么要封装成 ClientHandler? 解耦逻辑,让每个连接单独处理,逻辑清晰又好维护。你直接 inline 写代码以后哭的就是你。

  • 如果客户端断开了怎么办? 那就捕获异常呗,记得关闭 Socket 释放资源。这就是“防御式编程”。

  • 💡延伸一波,带你入点更深的坑

    这只是最基础的“阻塞式 BIO 多线程模型”。但在真实生产环境中你会发现:

    • 大量并发连接会拖死线程池
    • 阻塞 I/O 导致线程等待时间过长
    • 可扩展性差

    于是就有了:

    • NIO(非阻塞 IO):引入 Selector,一个线程可以监听多个通道
    • Netty:基于 NIO 封装的异步事件驱动框架,性能炸裂
    • Reactor/Proactor 模型:更细粒度的事件驱动方式

    你以为这篇文章结束了?不,我这是给你挖坑,下次就把 NIO 和 Netty 拿出来给你好好开堂大课 😎

    ✍️写在最后:代码你可以复制,理解必须原创!

    说真的啊,能坚持读到这里的,基本都是有点“技术洁癖”的人了,我敬你是条好汉。

    别小看这几十行代码,背后是线程、IO、网络编程、设计模式等一大串知识点的融合。理解了它,你就不是那种“面试手撕一堆,入职啥都不会”的纸老虎。

    📌总结

    项目内容
    技术点 Socket、多线程、线程池
    实战类型 多线程服务端 + 客户端通信
    编程语言 Java
    延伸方向 NIO、Netty、异步模型
    推荐人群 Java 初中高级开发者

    📣你还在用单线程服务?真的不考虑提升一下姿势水平?

    如果你看完觉得有帮助,不妨点个赞或者收藏,甚至留言互怼(别客气,我顶得住)。下篇我来手把手写 Netty,让你彻底摆脱“Socket = 土味代码”的误区。

    📝 写在最后

    如果你觉得这篇文章对你有帮助,或者有任何想法、建议,欢迎在评论区留言交流!你的每一个点赞 👍、收藏 ⭐、关注 ❤️,都是我持续更新的最大动力!

    我是一个在代码世界里不断摸索的小码农,愿我们都能在成长的路上越走越远,越学越强!

    感谢你的阅读,我们下篇文章再见~👋

    ✍️ 作者:某个被流“治愈”过的 Java 老兵 📅 日期:2025-07-02 🧵 本文原创,转载请注明出处。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 你还在用单线程处理请求?这年头还不会写多线程服务器,真的不慌吗?
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!