服务器本质上是一个项目队列,而客户端充当这些项目的生产者和/或消费者。
服务器必须:
- 监听 put / take 请求并相应地处理它们 - 这通常不会花费太长时间,它包括:
- 解析短字符串;
- 一个
HashMap.get
; - 获取锁;
- 一个
PriorityQueue.poll
或PriorityQueue.offer
;
- 尽快通知每个客户所有项目活动,以便每个客户实时了解正在发生的事情。
设置它的最简单方法是拥有一个线程accept
客户端,然后为每个客户端创建两个线程:
- 一个处理
InputStream
,它阻塞等待请求; - 另一个处理
OutputStream
,它侦听队列中的事件,并将信息发送给客户端。
当然这是不可扩展的,并且为每个客户端设置两个线程似乎很浪费。
我还考虑过使用单线程,这将
- 将套接字超时设置为
read
大约 1 秒; read
如果超时或处理请求后,继续将每个新事件发送给客户端;- 循环这两个动作。
但是,轮询请求和事件也是一种浪费。
另一种方法是使用线程池,并将上述两个动作中的每一个放在各自的Runnable
. 然后,这些可运行文件将在Executor
. 这似乎同样浪费,如果不是更多的话。
我一直在阅读一些 问题,现在我对 NIO 很好奇,因为非阻塞操作和事件驱动服务器似乎是正确的方法。
上述任何设计都适合这项任务,还是我应该用 NIO 来解决它?
就数字而言,这更像是一个练习,而不是一个真实的系统,因此它不必处理成千上万的客户,但理想情况下,它应该能够很好地执行和扩展。