【问题标题】:Serialized hashmap not updated序列化的 hashmap 未更新
【发布时间】:2016-10-17 08:21:29
【问题描述】:

在我的项目中,我有许多通过套接字进行通信的多线程进程。我在发送哈希图、更新它然后再次发送时遇到问题。 我在第二次发送后获得的地图值没有更新。 我在这个示例类中重现了这个问题:

package test;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;

public class Test {
    //TEST

        static class MyKey implements Serializable{
            String nome;
            String nomeM;
            int altro;
            public MyKey(String nome, String nomeM, int altro) {
                super();
                this.nome = nome;
                this.nomeM = nomeM;
                this.altro = altro;
            }
            @Override
            public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + ((nome == null) ? 0 : nome.hashCode());
                result = prime * result + ((nomeM == null) ? 0 : nomeM.hashCode());
                return result;
            }
            @Override
            public boolean equals(Object obj) {
                if (this == obj)
                    return true;
                if (obj == null)
                    return false;
                if (getClass() != obj.getClass())
                    return false;
                MyKey other = (MyKey) obj;
                if (nome == null) {
                    if (other.nome != null)
                        return false;
                } else if (!nome.equals(other.nome))
                    return false;
                if (nomeM == null) {
                    if (other.nomeM != null)
                        return false;
                } else if (!nomeM.equals(other.nomeM))
                    return false;
                return true;
            }

        }
        static class MyValue implements Serializable{
            int num;
            boolean bool;
            public MyValue(int num, boolean bool) {
                super();
                this.num = num;
                this.bool = bool;
            }
            public String toString() {
                return num + " " + bool;
            }
        }

        public static void main(String [] args) {
            final int port = 9876;
            final MyKey myKey = new MyKey("foo","bar",42);
            Thread writer = new Thread(new Runnable() {
                public void run() {
                    ServerSocket ss = null;
                    try {
                        ss = new ServerSocket(port);

                        ObjectOutputStream oos = new ObjectOutputStream(ss.accept().getOutputStream());

                        HashMap<MyKey,MyValue> map = new HashMap<>();

                        map.put(myKey, new MyValue(1,false));

                        System.out.println("writer step 1: "+map.get(myKey).toString());

                        oos.writeObject(map);
                        oos.flush();

                        map.put(myKey, new MyValue(0,true));


                        System.out.println("writer step 2: "+map.get(myKey).toString());


                        oos.writeObject(map);
                        oos.flush();

                        oos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
            Thread reader = new Thread(new Runnable() {
                public void run() {
                    try {
                        Socket s = new Socket("localhost",port);
                        ObjectInputStream ois = new ObjectInputStream(s.getInputStream());

                        HashMap<MyKey,MyValue> map = (HashMap<MyKey,MyValue>) ois.readObject();

                        System.out.println("reader step 1: "+map.get(myKey).toString());

                        map = (HashMap<MyKey,MyValue>) ois.readObject();

                        System.out.println("reader step 2: "+map.get(myKey).toString());

                        ois.close();
                        s.close();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            });

            writer.start();
            reader.start();
        }
        //FINE TEST
}

这是我得到的:

writer step 1: 1 false
writer step 2: 0 true
reader step 1: 1 false
reader step 2: 1 false

我也尝试将地图包装在另一个类中,但没有成功。

我错过了什么?

【问题讨论】:

  • 你有什么问题?

标签: java serialization hashmap


【解决方案1】:

这是因为在流中写入相同的对象(这里是您的地图)之前,您没有在 ObjectOutputStream 上调用 reset(),因此默认情况下它认为它已经在流中,这就是您继续使用的原因查看之前的状态。

重置将忽略任何已写入 溪流。状态被重置为与新的ObjectOutputStream 相同。 流中的当前点被标记为重置,因此 对应的ObjectInputStream 将在同一点重置。 之前写入流的对象不会被称为 已经在流中。它们将再次写入流中。

试试这个:

// Call reset before writing your map for the second time
oos.reset();
// Write the map
oos.writeObject(map);

输出:

writer step 1: 1 false
writer step 2: 0 true
reader step 1: 1 false
reader step 2: 0 true

【讨论】:

  • 非常感谢!所以关键是,在不调用reset的情况下,只要我发送一个'=='前一个对象,我都会得到对象的第一个状态。对吗?
  • @Svech87 是的,就是这个想法
猜你喜欢
  • 1970-01-01
  • 2016-09-12
  • 2011-08-26
  • 2011-10-29
  • 1970-01-01
  • 2011-04-23
  • 2015-12-23
  • 1970-01-01
  • 2023-03-04
相关资源
最近更新 更多