我有一台具有多个客户端的服务器。它使用一个服务器套接字和两个线程池来接收和处理来自远程客户端的请求:一个池-用于处理客户端连接,另一个池-用于处理客户端远程任务。每个客户端发送具有唯一任务ID(在每个连接中)和一堆参数的异步任务。任务反序列化后,服务器将查找相应的服务,在其上调用给定的方法,将结果和任务ID一起包装到答案对象中,然后使用ObjectOutputStream
将其发送回客户端。
由于任务是同时处理的,因此两个或多个线程可能同时完成一个客户端的处理任务,并尝试竞争ObjectOutputStream
。
接下来会发生什么?我的意思是说,他们是将对象写成原子输出流还是应该同步他们对ObjectOutputStream
的访问,以免出现一个线程写其对象一半的情况-然后另一个线程干预并... ,一种科学怪人对象将被发送到客户端。
import java.io.*;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.*;
public class Server {
private final ExecutorService connExecutor = Executors.newCachedThreadPool();
private final ExecutorService tasksExecutor = Executors.newCachedThreadPool();
public void start() {
try (ServerSocket socket = new ServerSocket(2323);) {
while (true) {
try (Socket conn = socket.accept()) {
connExecutor.execute(() -> {
try (ObjectInputStream in = new ObjectInputStream(conn.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(conn.getOutputStream())) {
while (true) {
Remotetask task = (Remotetask) in.readObject();
tasksExecutor.execute(() -> {
handletask(task,out);
});
}
} catch (IOException | ClassnotFoundException e) {
e.printStackTrace();
}
});
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void handletask(Remotetask task,ObjectOutputStream out) {
RemoteAnswer answer = new RemoteAnswer();
// unwrap remote task
// lookup local service
// invoke task's method
// wrap result into remote answer
// send answer to the client
try {
out.writeObject(answer);
} catch (IOException e) {
e.printStackTrace();
}
}
}