2016-10-17 83 views
2

在我的項目中我有許多多線程進程通過套接字進行通信。當我發送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

您有什麼問題在這? – Prasath

回答

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 
+0

非常感謝!所以問題是,如果沒有調用reset,任何時候我發送一個對象到前一個爲'==',我會得到對象的第一個狀態。是對的嗎? – Svech87

+0

@ Svech87是的,這是主意 –