Java资源试用。资源顺序
当我编写一个简单的rpc程序时,我遇到了一个奇怪的问题!我的英语很差,请查看代码。。。 下面的代码工作正常,但当我交换位于类Java资源试用。资源顺序,java,try-with-resources,Java,Try With Resources,当我编写一个简单的rpc程序时,我遇到了一个奇怪的问题!我的英语很差,请查看代码。。。 下面的代码工作正常,但当我交换位于类RpcImporter的try with block中的A和B的顺序时, 他们封锁了 RpcImporter RpcExporter RpcTest EchoServiceImpl EchoService 软件包演示1 公共接口回声服务{ 串回波(串ping); } 那么,为什么会发生这种情况呢?来自java文档: ObjectInputStream: ObjectIn
RpcImporter
的try with block
中的A和B的顺序时,
他们封锁了
RpcImporter
RpcExporter
RpcTest
EchoServiceImpl
EchoService
软件包演示1
公共接口回声服务{
串回波(串ping);
}
ObjectInputStream
:
ObjectInputStream创建从
指定的输入流。
从流中读取序列化流头并进行验证。
此构造函数将阻塞,直到相应的ObjectOutputStream
已写入并刷新标题
ObjectOutputStream
:
ObjectOutputStream创建一个ObjectOutputStream,用于写入指定的
输出流。此构造函数写入序列化流头
至下伏溪流;呼叫者可能希望刷新流
立即确保施工人员接收
ObjectInputStreams在读取标头时不会阻塞
因此,正如您所看到的,它明确指出,如果ObjectOutputStream
构造函数没有首先调用ObjectInputStream
构造函数,那么构造函数将被阻塞
换句话说,这是必须按顺序调用的2个特殊资源(ObjectOutputStream
constructor优先),否则ObjectInputStream
constructor将阻塞
(如果您使用的是1个线程…我交换A和B的顺序,其中是A和B
?
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();
}
});
}
}
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();
}
}
}
}
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 ?"));
}
}
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 ?"));
}
}
package demo1;
public interface EchoService {
String echo(String ping);
}