ObjectOutputStream (oos) / ObjectInputStream (ois) 實現對象 ↔ 二進制流轉換,支持文件、Socket 通道。
輸出流必須先於輸入流初始化,否則拋異常。原因:ObjectInputStream 構造器調用 readStreamHeader() 讀取雙 Short 值決定緩存大小,依賴對端 ObjectOutputStream 已寫入 Header。
// 文件通道
File file = new File("C:/data.dat");
oos = new ObjectOutputStream(new FileOutputStream(file));
ois = new ObjectInputStream(new FileInputStream(file));
// Socket 通道
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
// 注意:此處 oos/ois 對接的是 socket 另一端的流,需保證對端輸出流先打開。
readObject() 循環讀取,數據盡頭拋 EOFException 表示連接關閉/發送結束。start() 啟動線程後,線程與 Runnable 對象無關。對象僅是內存資源+代碼段。主線程 + GC 線程至少兩個線程共存。
wait():釋放當前對象所有鎖,進入等待集。sleep() 不釋放鎖。synchronized 代碼塊中調用(持有鎖)。notify() 隨機喚醒一個等待線程;notifyAll() 喚醒所有,由優先級競爭唯一鎖。外部強制掛起線程破壞封裝,易導致死鎖/數據不一致。面向對象要求對象自主控制生命周期。
class Parent { synchronized void f() {} }
class Child extends Parent {
synchronized void f() { super.f(); } // 同一線程同一對象重入
}
f() 加鎖 → 進入調用 super.f() 再次嘗試加鎖。synchronized 阻止其他線程在同一對象上加鎖,不阻止持有鎖的線程重入。序列化注意流初始化順序與 EOF 含義;多線程核心在理解「鎖屬於對象、線程爭搶鎖、重入機制、wait/notify 配合同步」。實踐中多用 java.util.concurrent 高級組件,少寫底層同步代碼。