Когда я пишу простую программу rpc, я столкнулся со странной проблемой! Мой английский плохой, пожалуйста, проверьте код ...
код ниже работает правильно, но когда я поменяю местами порядок A и B , который находится в try-with-block
класса RpcImporter
,
они заблокировали ...
RpcImporter
package demo1;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;
public class RpcImporter {
public S importer(final Class serviceClass, final InetSocketAddress address) {
return (S) Proxy.newProxyInstance(
serviceClass.getClassLoader(),
new Class[]{serviceClass.getInterfaces()[0]},
(proxy, method, args) -> {
try (Socket socket = new Socket(address.getHostName(), address.getPort());
// this is A
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
// this is B
ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
) {
System.out.println("start request");
output.writeUTF(serviceClass.getName());
output.writeUTF(method.getName());
output.writeObject(method.getParameterTypes());
output.writeObject(args);
return input.readObject();
}
});
}
}
RpcExporter
package demo1;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Calendar;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class RpcExporter {
static Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
public static void exporter(int port) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(port)) {
while (true) {
executor.execute(new ExporterTask(serverSocket.accept()));
}
}
}
private static class ExporterTask implements Runnable {
final Socket socket;
public ExporterTask(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
) {
String interfaceName = input.readUTF();
Class service = Class.forName(interfaceName);
String methodName = input.readUTF();
Class[] parameterTypes = (Class[]) input.readObject();
Object[] arguments = (Object[]) input.readObject();
Method method = service.getMethod(methodName, parameterTypes);
Object result = method.invoke(service.newInstance(), arguments);
output.writeObject(result);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
RpcTest
package demo1;
import java.io.IOException;
import java.net.InetSocketAddress;
public class RpcTest {
public static void main(String[] args) throws Exception {
new Thread(() -> {
try {
RpcExporter.exporter(38088);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
RpcImporter importer = new RpcImporter();
EchoService echoService = importer.importer(EchoServiceImpl.class, new InetSocketAddress("localhost", 38088));
System.out.println(echoService.echo("Are you ok ?"));
}
}
EchoServiceImpl
package demo1;
import java.io.IOException;
import java.net.InetSocketAddress;
public class RpcTest {
public static void main(String[] args) throws Exception {
new Thread(() -> {
try {
RpcExporter.exporter(38088);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
RpcImporter importer = new RpcImporter();
EchoService echoService = importer.importer(EchoServiceImpl.class, new InetSocketAddress("localhost", 38088));
System.out.println(echoService.echo("Are you ok ?"));
}
}
EchoService
package demo1;</p>
<p>public interface EchoService {
String echo(String ping);
}</p></li>
</ol>
<p>
Итак, почему это могло произойти?