尝试序列化并将Lot
对象发送到套接字。得到错误:
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;
}
}
答案 0 :(得分:5)
错误是由尝试序列化ClientServiceThread
引起的,Lot
不可序列化。不知何故,其中一个是Lot
的一部分。如果未使用ClientServiceThread
字段(或包含ClientServiceThread
的字段)声明Lot
,则另一种可能性是Lot
是非静态内部类一个确实有这样一个领域的类。然后外部类实例将成为ClientServiceThread
的(隐藏)成员。
解决方案是使transient
可序列化(不太可能来自其名称),或者通过标记相关字段Lot
(或从{{1}}中删除它们来将其从序列化中消除) {1}}类)。
答案 1 :(得分:4)
Lot
包含
public ArrayList<ClientServiceThread> clientBidsLog
private List<ClientServiceThread> clients
如果您希望序列化此字段,请标记ClientServiceThread
serializable
如果您不希望序列化,只需将其标记为transient
public transient ArrayList<ClientServiceThread> clientBidsLog
private transient List<ClientServiceThread> clients
答案 2 :(得分:2)
有几个答案表明您可以将ClientServiceThread
序列化声明为可能的解决方案。
警告 - 这可能不起作用!
是的,您可以声明实现Thread
的{{1}}子类,但Java序列化机制无法序列化活动线程的堆栈。事实上,我甚至认为它不会成功地序列化非活动线程的状态(例如线程的Serializable
引用),所以你可能会得到更多例外。
我认为您唯一的选择是通过将这些集合声明为ThreadGroup
来排除序列化中的线程。