clientSocket.getOutputStream().write(response.getBytes());
clientSocket.close();
System.out.println(threadName + ” 完成请求处理”);
} catch (IOException | InterruptedException e) {
System.err.println(“处理请求时出错: ” + e.getMessage());
}
}
}
public static void main(String[] args) {
SimpleWebServer server = new SimpleWebServer(8080, 10);
// 添加关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread(server::stop));
try {
server.start();
} catch (IOException e) {
System.err.println(“服务器启动失败: ” + e.getMessage());
}
}
}
这个简单的Web服务器展示了如何利用线程池处理并发连接,每个请求都在独立的线程中处理,提高了服务器的吞吐量。
最佳实践与性能优化
在多线程编程中,遵循最佳实践可以避免常见陷阱并提高性能:
1. 避免死锁
- 按固定顺序获取锁
- 使用带超时的锁获取机制
- 尽量避免嵌套锁
2. 减少锁竞争
- 缩小同步范围,只同步必要部分
- 使用读写锁(ReentrantReadWriteLock)分离读/写操作
- 考虑使用无锁数据结构(如Atomic变量)
3. 线程池配置建议
- CPU密集型任务:线程数 ≈ CPU核心数
- I/O密集型任务:线程数可以更多(如CPU核心数×2)
- 使用有界队列避免内存溢出
- 为线程设置有意义的名字,便于调试
4. 异常处理
为线程设置未捕获异常处理器:
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { System.err.println("线程 " + thread.getName() + " 发生未捕获异常: " + throwable.getMessage()); });
5. 使用现代并发工具
优先使用java.util.concurrent包中的高级工具:
- CountDownLatch:等待多个操作完成
- CyclicBarrier:同步多个线程的执行点
- Semaphore:控制资源访问权限
- CompletableFuture:异步编程模型