我遇到了以下问题:
所以这是我的解决方案,因为我在多线程/ tcp中没有经验,我想知道这是一个很好的解决方案吗?如果没有,有没有更好的解决方案?是否有必要为每个客户端套接字都有一个线程?谢谢 顺便说一句:抱歉让每个人感到困惑,这是一个只涉及5-10个班级的小项目。
class AcceptThread {
......
public void run () {
ControlThread controlThread = new ControlThread();
controlThread.start();
Socket socket = new Socket(port);
while (!stop) {
Socket s = socket.accept();
controlThread.addClient (s);
}
}
}
class ControlThread {
Set<Scoket> clients;
SendDataThread sendDataThread;
public ControlThread () {
sendDataThread = new SendDataThread();
sendDataThread.start();
}
public void addClient (Socket socket) {
clients.add(socket);
sendDataThread.addListener(socket);
}
public void run () {
......
for (Socket s : clients) {
if (s.getInputStream().available()) {
//read command from s
}
}
......
}
}
class SendDataThread () {
Set<Scoket> listeners;
public void addListener (Socket s) {
listeners.add(s);
}
public void run () {
for (Socket s: listeners) {
// send data to each listener
}
}
}
答案 0 :(得分:3)
是否需要为每个客户端套接字创建一个线程?
不,事实上,我甚至不推荐它。如果这是一个小项目,而您不想使用任何现有的库,我建议您使用java.nio
package和SelectableChannels
。使用所谓的选择器,您可以轻松地以非阻塞方式监视客户端的传入数据。
以下是一些有用的链接:
答案 1 :(得分:0)
答案 2 :(得分:0)
谢谢顺便说一句:抱歉让每个人感到困惑,这是一个只涉及5-10个课程的小项目。
这绝对没有错。所有更高级别的抽象都是基于套接字的方式。除非您的项目足够大,否则无需拉出一系列其他框架/工具包来执行相同的工作。线程很便宜(甚至可以从多核架构中受益),尽管使用SelectableChannels
作为@aioobe建议也不是一个坏主意。
当您的项目需要它时,您可以随时了解其他进程间通信方法(消息传递,远程方法调用等,以及它的大约100个实现)。
但是,您可能希望限制服务器同时使用的线程数。这可以通过声称例如大小等于您想要服务的线程数的信号量来容易地实现。另一个有趣的事情是使用java thread pools来更好地重用您的资源。
答案 3 :(得分:-1)
其他人提到过你可以使用nio库来减少必要的线程数。我只是想指出你当前的示例代码不起作用。在使用标准io流时,必须每个套接字使用一个线程。 available()
方法几乎没用(通常)并且不会阻止你的控制线程阻塞。