2012-06-06 66 views
2

尝试序列化并将Lot对象发送到套接字。获取错误:尝试写入对象时获取NotSerializableException

java.io.NotSerializableException: com.server.ClientServiceThread 

为什么?

public class ClientServiceThread extends Thread {... // form here called sendObj ...} 

public class FlattenLot { 
public void sendObj(){ 
     try { 
      out = new ObjectOutputStream(oStream); 
      out.writeObject(lot); // error 
      out.flush(); 
      out.close(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
    } 

很多课:

import java.io.Serializable; 
import java.util.ArrayList; 
import java.util.List; 

import java.util.Date; 
import java.util.Calendar; 

public class Lot implements Serializable{ 
private static final long serialVersionUID = 1L; 
    public ArrayList<ClientServiceThread> clientBidsLog = new ArrayList<ClientServiceThread>(); 
    public ArrayList<Integer> bidLog = new ArrayList<Integer>(); 

    private List<Integer> bids = new ArrayList<Integer>(); 
    private List<ClientServiceThread> clients = new ArrayList<ClientServiceThread>(); 

    private String NAME; 
    private int INITIAL_PRICE; 

    private int MAX_BID = 0; 
    public volatile boolean notAvailable = false; 
Lot(String name, int initPrice){ 
     NAME = name; 
     INITIAL_PRICE = initPrice; 
    } 
public synchronized String getName(){return NAME;} 
public synchronized int getInitPrice(){return INITIAL_PRICE;} 
public synchronized void subscribe(ClientServiceThread t){ 
     clients.add(t); 
     } 
public synchronized void unsubscribe(ClientServiceThread t){ 
     clients.remove(t); 
     } 
public synchronized boolean makeBid(ClientServiceThread t,int i){ 
      if(i > INITIAL_PRICE && i > MAX_BID){ 
       clientBidsLog.add(t); 
       bidLog.add(i); 
       bids.add(i); 
       MAX_BID = i; 
       t.LAST_BID = i; 
       notifyAllSubscribers("New bid: "+this.getMaxBid()+" made by "+this.clientBidsLog.get(this.clientBidsLog.size()-1).CLIENT_NAME); 
       return true; 
      }else{ 
       return false; 
      } 


      } 
public synchronized void notifyAllSubscribers(String msg){ 
     for (ClientServiceThread client : clients){ 
       client.lotUpdated(this, msg); 
      } 
    } 
public synchronized int getMaxBid(){return MAX_BID;} 

    private Date time; 

    public Lot() { 
     time = Calendar.getInstance().getTime(); 
    } 

    public Date getTime() { 
     return time; 
    } 
    } 
+2

为什么你需要序列化一个线程? –

+0

我序列化* Lot *对象。从Thread发送数据到客户端的writeObject方法。 –

+1

'Lot'有哪些字段? –

回答

4

Lot包含

public ArrayList<ClientServiceThread> clientBidsLog 
private List<ClientServiceThread> clients 

如果你希望这个字段被序列标记ClientServiceThreadserializable

,如果你不希望它只是做连载纪念它transient

public transient ArrayList<ClientServiceThread> clientBidsLog 
private transient List<ClientServiceThread> clients 
+4

或者将该字段标记为“transient”,以便不将其包含在序列化中。 –

+1

不要忘记'Private List clients'属性。 –

5

错误是由试图序列化ClientServiceThread,这是不序列化造成的。不知何故,其中一个是Lot的一部分。如果Lot未声明ClientServiceThread字段(或字段包含ClientServiceThread),则另一种可能性是Lot是具有此类字段的类的非静态内部类。外部类实例将成为Lot的(隐藏)成员。

的解决方案是要么使ClientServiceThread序列化(不太可能,从它的名字),或者通过标记相关领域(S)transient(或从Lot类中删除它们)从序列消除它。

2

有几个答案建议您可以声明ClientServiceThread se可作为可能的解决方案。

警告 - 这可能不起作用!

是的,您可以声明一个Thread子类,它实现Serializable,但Java序列化机制无法序列化活动线程的堆栈。实际上,我甚至不认为它会成功地序列化一个非活动线程的状态(例如线程的ThreadGroup引用),所以你可能会得到更多的异常。

我认为你唯一的选择是通过声明这些集合为transient排除序列化的线程。

相关问题