我想通过Java通过Socket发送数据包。但是我应该如何处理它以获得最佳性能和最小的故障风险?
我已经尝试过分离线程。一个正在接收,第二个正在处理分组数据。但是处理Queue的速度很快,我备份了1个线程。所以最后我认为应该有更好的方法,因为如果应用程序要长时间处理数据包,其他数据包也需要等待。
while(!isInterrupted()) {
try {
byte[] data = new byte[2];
is.readFully(data);
//GET PACKET ID
short id = ByteBuffer.wrap(data).getShort();
data = new byte[4];
is.readFully(data);
//GET PACKET SIZE
int size = ByteBuffer.wrap(data).getInt();
data = new byte[size];
is.readFully(data);
//GET DATA
Main.getInstance().getPacketHandler().handle(id, data);
} catch (IOException e) {
e.printStackTrace();
break;
}
}
public void handle(short id, byte[] b) {
//GET PACKET TYPE BY ID
PacketType type = PacketType.getById(id);
//CREATE EVENT FROM PACKET
Event event = type.getPacket(b).createEvent();
//EXECUTE EVENT TO EVERY REGISTERED LISTENER TO PROCESS DATA
for(PacketListenerInfo listener : listeners) {
for(Method method : listener.methods) {
if(method.getParameterTypes()[0].isInstance(event)) {
try {
method.invoke(listener.listener, event);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
就像我之前提到的,我已经尝试过这样做,但是queue
列表很快就被填满了:
private Queue<HandlePacket> queue = new LinkedList<>();
public void handle(short id, byte[] b) {
queue.add(new HandlePacket(id, b));
synchronized (this) {
notify();
}
}
private class HandlePacket{
short id;
byte[] b;
public HandlePacket(short id, byte[] b) {
this.id = id;
this.b = b;
}
}
@Override
public void run() {
while(!isInterrupted()) {
if(queue == null || queue.isEmpty()) {
try {
synchronized (this) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
HandlePacket hp = queue.poll();
if(hp != null) {
PacketType type = PacketType.getById(hp.id);
Event event = type.getPacket(hp.b).createEvent();
for(PacketListenerInfo listener : listeners) {
for(Method method : listener.methods) {
if(method.getParameterTypes()[0].isInstance(event)) {
try {
method.invoke(listener.listener, event);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
}
}
答案 0 :(得分:0)
最后(对于我个人而言)最好的解决方案是:
public void handle(short id, byte[] b) {
data.add(new HandlePacket(id, b));
executor.execute(new Processor(data));
}
class Processor implements Runnable {
private BlockingQueue<HandlePacket> dataSource;
public Processor(BlockingQueue<HandlePacket> dataSource) {
this.dataSource = dataSource;
}
@Override
public void run() {
HandlePacket hp = null;
while ((hp = dataSource.poll()) != null) {
if(hp != null) {
PacketType type = PacketType.getById(hp.id);
if(type == null) {
continue;
}
Event event = type.getPacket(hp.b).createEvent();
for(PacketListenerInfo listener : listeners) {
for(Method method : listener.methods) {
if(method.getParameterTypes()[0].isInstance(event)) {
try {
method.invoke(listener.listener, event);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
}
}
}