Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java多线程有状态服务器网络设计_Java_Multithreading_Sockets - Fatal编程技术网

Java多线程有状态服务器网络设计

Java多线程有状态服务器网络设计,java,multithreading,sockets,Java,Multithreading,Sockets,我正在尝试实现一个有状态的多客户端服务器应用程序,对网络/线程设计有一些疑问。我目前面临的问题是如何在通信层和逻辑层之间交换消息 服务器处理多个客户端,其中每个客户端可以在多个“通道”中活动,其中每个通道具有多个阶段,并且可能有多个客户端在其中活动。把它想象成一个类似于多个聊天室的聊天程序 我已经在服务器端实现了消息的接收。每个客户机都有自己的线程,该线程以块方式读取数据并解码为消息。现在如何进行?在我看来,每个频道也应该有自己的线程,以便轻松地维护其状态。我可以使用BlockingQueue与

我正在尝试实现一个有状态的多客户端服务器应用程序,对网络/线程设计有一些疑问。我目前面临的问题是如何在通信层和逻辑层之间交换消息

服务器处理多个客户端,其中每个客户端可以在多个“通道”中活动,其中每个通道具有多个阶段,并且可能有多个客户端在其中活动。把它想象成一个类似于多个聊天室的聊天程序

我已经在服务器端实现了消息的接收。每个客户机都有自己的线程,该线程以块方式读取数据并解码为消息。现在如何进行?在我看来,每个频道也应该有自己的线程,以便轻松地维护其状态。我可以使用BlockingQueue与通道线程交换收到的消息,通道线程正在阻塞地等待队列中的新消息

那么,如何向客户发送消息呢?通道中的逻辑将处理消息,并生成一些消息发送给一个/一些/所有客户端。使用通道线程直接写入套接字是否安全?还是应该使用另一个BlockingQueue将消息传输到客户端处理程序线程?但是如何唤醒它,因为它正在等待套接字读取?或者我应该为每个客户端使用一个单独的发送线程,或者甚至是一个单独的发送套接字


顺便说一句:我知道我可以将现有库用于网络层,但我想在普通套接字上从头开始使用。

事件机制如何?当您准备好处理请求并且有一个客户端数据可用时,只需将其与客户端套接字处理程序线程的事件一起发送即可。由于来自客户端的传输已结束,如果我认为正确,您可以正常发送回复。

在封装套接字的通信对象上放置一个send message方法。同步此方法,以便一次只能有一个线程调用它。那么,有多少线程调用这个方法没有任何区别。每条消息一次只发送一条。您也不必干扰正在阻止读取的线程。这个send方法将是一个足够快的操作,您不必担心线程发送时其他线程阻塞

只要通道对每个连接的客户机的通信对象都有引用,它就可以发送消息而不必担心


如果它曾经导致问题,您可以随时修改该发送消息以使要发送的对象排队。然后,您可以在队列上阻塞一个特定的发送线程,并将内容写入套接字。但根据我的经验,这是不必要的。

如果处理成本低且是每条消息,我不确定是否会使用多线程。我会考虑用反应堆代替。每个客户端和/或通道都有状态这一事实并不意味着您必须使用线程。我假设您指的是NIO。我阅读了这篇比较NIO/IO的文章,因此我选择每个连接使用一个线程(这已经实现了)。但对于频道,可以选择另一种方法。。。然而,实际的问题将是与我所说的“直接写入套接字”相同的问题,这是一个坏消息。但对我来说,有一个线程用于“读取输入消息”,另一个线程用于“处理消息并向多个客户端写入响应”,这似乎很奇怪。但也许这正是我对线程任务解耦的爱好……难道你的通道线程不会处理消息并向多个通信对象写入响应吗?我不明白为什么你需要在这个线程和你的通信对象之间做任何事情。实际上,该线程将通过通信对象直接写入所有套接字。