首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java尝试-使用资源。资源顺序

Java尝试-使用资源。资源顺序
EN

Stack Overflow用户
提问于 2018-09-03 08:42:21
回答 1查看 89关注 0票数 1

当我编写一个简单的rpc程序时,我遇到了一个奇怪的问题!我的英语很差,请查一下密码.下面的代码工作正常,但是当我交换AB的顺序,它们位于RpcImporter类的try-with-block中,它们阻止了.

  1. RpcImporter
代码语言:javascript
复制
    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();
                        }

                    });

        }
    }
  1. RpcExporter
代码语言:javascript
复制
    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();
                }
            }
        }
    }
  1. RpcTest
代码语言:javascript
复制
    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 ?"));
        }
    }
  1. EchoServiceImpl
代码语言:javascript
复制
    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 ?"));
        }
    }
  1. EchoService

包demo1;公共接口EchoService {字符串回波(字符串ping);}

为什么会发生这种事?

EN

回答 1

Stack Overflow用户

发布于 2018-09-03 14:41:54

来自java文档:

ObjectInputStream

ObjectInputStream创建一个从指定的InputStream读取的ObjectInputStream。从流中读取序列化流头并进行验证。此构造函数将被阻塞,直到相应的ObjectOutputStream编写和刷新了标头。

ObjectOutputStream

ObjectOutputStream创建一个写入指定OutputStream的ObjectOutputStream。此构造函数将序列化流头写入基础流;调用方可能希望立即刷新流,以确保用于接收ObjectInputStreams的构造函数在读取标头时不会阻塞。

因此,正如您所看到的,它明确指出,如果ObjectOutputStream构造函数没有首先调用,ObjectInputStream构造函数将被阻塞。

换句话说,这是两个必须按顺序调用的特殊资源(首先是ObjectOutputStream构造函数),否则ObjectInputStream构造函数将被阻塞。

(如果您使用的是1线程.)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52146106

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档