2013-03-03 131 views
-1

我有以下代碼結構。Java對象返回默認值

Transaction類型的事務處理程序,它是Client Handler類中的一個字段,與Server進行通信。 (客戶端處理程序和服務器是並置的),客戶端通過序列化的對象消息與客戶端處理程序通信。

當一個新的事務請求從客戶端進入時(使用對象輸入流的readObject()方法進入線程),然後執行一系列trx_handler.setFoo(trx.getFoo)))。這工作正常,我可以處理第一個請求。但是當後續請求進入時(由於循環結構,第一個請求完成後纔開始執行),我發現trx處理程序已重新初始化爲默認值,對象仍然存在,但其中的所有值都是該defaut的人,是什麼原因這個問題?

我的第一個猜測是垃圾回收,但在我的客戶端處理程序類,總有一個指向該trx_handler。

下面的代碼說明會發生什麼。一語句首先是start類型的,所以trx_handler將被正確初始化,然後調用handle_statement,然後接收後續語句,但是此時trx_handler已經被重新初始化爲默認設置,所以access_set fie LD爲null,會話ID爲好,並沒有在hande_statement對象進行的修改是可見的

感謝

public class Handler { 

    private Statement trx_handler; 

/* Constructor initialises trx_handler to new Statement(); */ 

public ClientHandler(final Socket socket, long uid, Server server, ObjectInputStream ois) throws   IOException, Exception { 
LOGGER.info("Constructing Handler"); 
this.uid = uid; 
this.server = server; 
this.socket = socket; 
this.database = server.getDB(); 
this.trx_sys = database.getTransactionManager(); 
create_listening(socket, ois); 
out = socket.getOutputStream(); 
oos = new ObjectOutputStream(out); 
this.trx_handler = new Statement(false); 

}

private void create_incoming(final Socket socket, final ObjectInputStream stream) { 
    Thread incoming = new Thread() { 
    @Override 
    public void run() { 
    ObjectInputStream ois = stream; 
    InputStream in = null; 
    while (true) { 
     Object statement = null; 

     try { 

     statement = ois.readObject(); 
     execute_stat(statement, socket, null); 
     LOGGER.info("Ready to execute next "); 
     } catch (SocketException e) { 
     LOGGER.severe("Connection Closed"); 
     return; 
     } catch (IOException e) { 
     LOGGER.severe("Connection Closed"); 
     return; 
     } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
     } catch (Exception e) { 
     e.printStackTrace(); 
     String error_message = e.getMessage(); 
     send_error(socket, error_message); 
     } 

    } 
    } 
}; 
incoming.setDaemon(true); 
incoming.start(); 

} 

private synchronized void execute_stat(Statement trx) { 
    if (trx.getTransactionState() == Consts.trx_end) { 
    trx_sys.commitTransaction(trx_handler); 
    return; 
    } else if (trx.getTransactionState() == Consts.trx_start) { 
    try { 
    trx_handler.setAccessSet(trx.getAccessSet()); 
    trx_handler.setSession_id(trx.getSession_id()); 
    trx_sys.startTransaction(trx_handler); 
    handle_statement(socket, trx_handler); 


    /* TEST HERE THAT FIELDS IN TRX_HANDLER ARE CORRECTLY SET (INCLUDING SOME MODIFIED IN  
    handle_statement and they are correctly set */ 

    return; 
    } catch (Exception ex) { 
    Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 
try { 
    LOGGER.info("Execute Trx: stat"); 

    /* Can't see modifications made in the start case */ 
    Statement stats = trx.getStatement(); 
    trx_handler.setStatement(stats); 
    handle_statement(stats, socket, trx_handler); 

} catch (Exception e) { 
    e.printStackTrace(); 

} 

return; 
} 
+1

這與垃圾收集無關,可能是您的代碼中的一個錯誤。我不認爲我們能夠根據迄今爲止提供的信息來猜測錯誤是什麼。考慮再調試一些,然後發佈更多相關的代碼和信息。 – 2013-03-03 00:43:26

+0

(更新後添加更詳細的代碼) – user1018513 2013-03-03 08:34:08

回答

0

你需要或者發送一個品牌每個交易的新對象,使用ObjectOutputStream.writeUnshared(),否則在發送之間調用ObjectOutputStream.reset()

+0

問題不在於通過輸出流發送的對象(我已經使用reset),而是在客戶端處理程序中使用字段對象,由於某些原因似乎重新初始化爲兩個句柄語句調用之間的默認字段值。 – user1018513 2013-03-03 08:20:48

+0

@ user1018513真的嗎?你有沒有讀過Javadoc?你是否知道,如果第二次用不同的值發送同一個對象兩次,你將不會收到改變的值?你有沒有嘗試*這些建議? – EJP 2013-03-03 08:42:23

+0

是的,並實施它們。我在對象流中收到的Statement對象包含正確的值。這是trx處理程序被重置。 – user1018513 2013-03-03 08:45:01