Java 一个数据报接收器需要多少线程?
我为我用java(和LWJGL)创建的游戏创建了一个收发数据报系统 然而,这些数据报经常被丢弃。这是因为服务器在主循环中等待各种IO操作和其他处理完成,同时向其发送新的数据报(显然它没有监听) 为了解决这个问题,我使用while-true循环来捕获数据报,但是我没有在主线程中进行处理,而是将分支扩展到不同的线程 像这样:Java 一个数据报接收器需要多少线程?,java,multithreading,sockets,udp,datagram,Java,Multithreading,Sockets,Udp,Datagram,我为我用java(和LWJGL)创建的游戏创建了一个收发数据报系统 然而,这些数据报经常被丢弃。这是因为服务器在主循环中等待各种IO操作和其他处理完成,同时向其发送新的数据报(显然它没有监听) 为了解决这个问题,我使用while-true循环来捕获数据报,但是我没有在主线程中进行处理,而是将分支扩展到不同的线程 像这样: ArrayList<RecieveThread> threads = new ArrayList<RecieveThread>(); public vo
ArrayList<RecieveThread> threads = new ArrayList<RecieveThread>();
public void run(){
while (true){
//System.out.println("Waiting!");
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
try {
socket.receive(packet);
} catch (IOException e) {
e.printStackTrace();
}
//System.out.println("Recieved!");
String str = new String(packet.getData());
str = str.trim();
if (threads.size() < 50){
RecieveThread thr = new RecieveThread();
thr.packet = packet;
thr.str = str;
threads.add(thr);
thr.start();
}else{
boolean taskProcessed = false;
for (RecieveThread thr : threads){
if (!thr.nextTask){
thr.packet = packet;
thr.str = str;
thr.nextTask = true;
taskProcessed = true;
break;
}
}
if (!taskProcessed){
System.out.println("[Warning] All threads full! Defaulting to main thread!");
process(str, packet);
}
}
}
}
ArrayList threads=new ArrayList();
公开募捐{
while(true){
//System.out.println(“等待!”);
字节[]数据=新字节[1024];
DatagramPacket数据包=新的DatagramPacket(数据,数据.长度);
试一试{
套接字接收(数据包);
}捕获(IOE异常){
e、 printStackTrace();
}
//System.out.println(“received!”);
String str=新字符串(packet.getData());
str=str.trim();
if(threads.size()<50){
ReceiveThread thr=新ReceiveThread();
thr.packet=分组;
thr.str=str;
螺纹。添加(thr);
thr.start();
}否则{
布尔值=false;
用于(接收线程数:线程数){
如果(!thr.nextTask){
thr.packet=分组;
thr.str=str;
thr.nextTask=true;
taskProcessed=true;
打破
}
}
如果(!taskProcessed){
System.out.println(“[警告]所有线程已满!默认为主线程!”);
过程(str,packet);
}
}
}
}
这就是为每个传入的数据报创建一个新线程,直到它到达50个数据包,此时它选择在一个等待下一个任务的现有线程中进行处理——如果所有线程都在处理,则默认为主线程
所以我的问题是:多少线程是一个好的数量?我不想让任何人的系统过载(同样的代码也会在玩家的客户端上运行),但我也不想增加系统的数据包丢失
另外,不同的线程是一个好主意吗?有人有更好的方法吗
编辑:这是我的ReceiveThread类(类长777行):
String-str;
数据包;
布尔值nextTask=true;
公开募捐{
while(true){
////System.out.println(“客户:+str”);
//赛前
而(!nextTask){
//没什么
}
}
}
关于使用NginX或Apache的疑问,您似乎也遇到了同样的问题。你读过关于NginX和10k问题的书吗?如果没有,请阅读。像这样的问题没有“正确”的答案。正如其他同事所强调的,这个问题是关于应用程序环境的需求(方面)。请记住,我们有这么多的web框架:每个框架都解决了相同的问题,即服务于html文档的内容,但使用不同的方法来完成任务。可能只有一个线程,假设您有一个
DatagramSocket。
您总是可以从读取UDPSocket的线程中生成一个processData线程。正如人们在评论中所说,这取决于你,但通常一个是好的
编辑:
如果您这样做的话,还可以查看互斥体。首先,任何使用数据报(如UDP)进行通信的系统都必须能够处理丢弃的请求。它们会发生的。你能做的最好的事情就是将典型的下降率降低到可以接受的程度。但您还需要认识到,如果您的应用程序无法处理丢失的数据报,那么它就不应该使用数据报。改用普通插座 现在来看看要使用多少线程的问题。答案是“视情况而定”
- 一方面,如果没有足够的线程,可能会有未使用的硬件容量(核心)在高峰时间使用。。。但事实并非如此
- 如果一次运行(或可运行)的线程太多,它们将在不同级别争夺资源:
- CPU竞争
- 内存带宽竞争
- 锁和共享内存上的争用
- 如果您的请求处理涉及到与其他机器上的数据库或服务器对话,那么您需要足够的线程来允许在等待响应时发生其他事情
请注意,如果线程太多,并且由于资源争用而陷入困境,也会发生同样的情况。通常没有神奇的t数
String str;
DatagramPacket packet;
boolean nextTask = true;
public void run(){
while (true){
////System.out.println("CLIENT: " + str);
//BeforeGame
while (!nextTask){
//Nothing
}
<Insert processing code here that you neither know about, nor care to know about, nor is relevant to the issue. Still, I pastebinned it below>
}
}