在我的项目中,我有许多通过套接字进行通信的多线程进程。我发送一个hashmap,更新它,然后再发送一个问题。 我没有更新第二次发送后得到的地图值。 我在这个示例类中重现了这个问题:
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
我也尝试将地图包装在另一个类中,但我没有成功。
我缺少什么?
答案 0 :(得分:0)
这是因为你没有在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