-1

我正在学习 Java NIO API,并且能够理解除了attachment对象之外的东西是如何工作的。

据我了解,我们可以创建channels类似socketChannels并将对象附加到它们。每当给定通道上有事件时,我们就可以拾取它及其附加对象。

在这里,我需要修改此对象(再添加一个 key 和 value )并将其注册到另一个频道 say upstream channel。考虑负载均衡器 - 从前端获取请求并将其传递给upstream channel

问题是当我修改对象时upstream channel,它socket channel也会被修改。

要检查这一点 - 我已经简化了代码。你能告诉我如何attachement工作吗?


public class Main {
    public static void main(String[] args)  {

        try{
            Selector selector = Selector.open();
            ServerSocketChannel serverSocket = ServerSocketChannel.open();
            serverSocket.bind(new InetSocketAddress("localhost", 10000));  
            serverSocket.configureBlocking(false);

            HashMap<String, Object> attr = new HashMap<>();
            attr.put("channel_type","server");
            attr.put("back_connection", "");

            SelectionKey selectionKey = serverSocket.register(selector, SelectionKey.OP_ACCEPT);
            selectionKey.attach(attr);  ----> 1 . I attach a object


            while(true){

                selector.selectNow();
                Set<SelectionKey> selectionKeySet = selector.selectedKeys();
                Iterator<SelectionKey> iter = selectionKeySet.iterator();
                while(iter.hasNext()){

                    selectionKey = iter.next();
                    attr = (HashMap)selectionKey.attachment();  ------> 3. Get the attachment object again from selectionKey 

                    System.out.println(selectionKey.channel());
                    String channelType = (String)attr.get("channel_type");
                    System.out.println( "Key is " + attr);  -----> 4. It has random_value key is present in attr  

                    if(selectionKey.isAcceptable() && channelType.equals("server")){

                        System.out.println("Server Connection is connected");
                        UUID uuid = UUID.randomUUID();
                        attr.put("random_value", uuid.toString());  ---> 2. Here I have modified the attr object

                    }


                    iter.remove();
                }

            }
        }

        catch(Exception e){
            System.out.println("Exception has occured in socket " + e);
        }
    }

我的问题是,当我random_value在 hashmap 中添加一个键时,附件对象如何serverSocket自动更改。

根据我的理解,只有当我再次使用通道的 selectionKey 附加修改后的对象时,它才会发生变化。

4

1 回答 1

0

Java 是按值传递,但对象变量是引用,所以

selectionKey.attach(attr);

传递attr. _ 只有引用保存在SelectionKey; 没有制作副本attr。因此,当您添加到 时attrSelectionKey对象会看到更改。

于 2022-01-18T04:33:21.830 回答