2013-03-03 2 views
-1

다음 코드 구조를 가지고 있습니다.Java 객체가 기본값으로 돌아 가기

서버와 통신하는 클라이언트 처리기 클래스의 필드 인 트랜잭션 유형의 트랜잭션 처리기입니다. (클라이언트 핸들러와 서버가 함께 배치 된 경우) 클라이언트는 직렬화 된 오브젝트 메시지를 통해 클라이언트 핸들러와 통신합니다.

새로운 트랜잭션 요청이 클라이언트에서 들어 오면 (객체 입력 스트림의 readObject() 메소드를 사용하여 스레드에서 발생 함) 일련의 trx_handler.setFoo (trx.getFoo)))). 이 잘 작동, 나는 첫 번째 요청을 처리 할 수 ​​있습니다. 그러나 후속 요청이 들어 오면 (루프 구조로 인해 첫 번째 요청이 완료된 후에 만 ​​실행되기 시작하면 trx 핸들러가 기본값으로 다시 초기화되고 객체는 여전히 있지만 그 안의 모든 값은 defaut에 사람이. 이것이 문제가 발생할 수 있습니까?

내 첫번째 추측은 가비지 컬렉션,하지만 내 클라이언트 핸들러 클래스에, 항상이 trx_handler에 대한 포인터가있는 것입니다.

아래 코드는 어떻게되는지 보여줍니다.을 trx_handler가 올바르게 초기화 될 것이므로 handle_statement가 호출 될 것입니다. 그 다음에 다음 문장이 수신되어야합니다. 그러나이 시점에서 trx_handler는 기본 설정으로 다시 초기화되므로 access_set fie LD뿐만 아니라, 세션 ID는 null이며, 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

이것은 가비지 수집과 아무 관련이 없으며 코드의 버그 일 가능성이 큽니다. 지금까지 제공된 정보를 기반으로 버그가 무엇인지 추측 할 수는 없을 것이라고 생각합니다. 좀 더 디버깅을하고보다 관련성 높은 코드와 정보를 게시하십시오. –

+0

(더 자세한 코드를 추가하기 위해 업데이트 됨) – user1018513

답변

0

각 트랜잭션에 대한 새 개체는 ObjectOutputStream.writeUnshared()을 사용하거나 송신간에 ObjectOutputStream.reset()을 호출하십시오.

+0

문제는 클라이언트 처리기에서 필드 개체와 함께 출력 스트림 (예 : 이미 초기화를 사용하고 있습니다)을 통해 보내는 개체와 관련이 없습니다. 두 핸들 문 호출 사이의 기본 필드 값으로 다시 초기화 된 것으로 보인다. – user1018513

+0

@ user1018513 정말요? Javadoc을 읽었습니까? 동일한 값을 다른 값으로 두 번 두 번 보내면 변경된 값을받지 못한다는 것을 알고 있습니까? 이 제안들 중 어떤 것을 시도해 보셨습니까? – EJP

+0

예, 구현했습니다. 객체 스트림에서받는 Statement 객체에는 올바른 값이 들어 있습니다. 리셋되는 것은 trx 핸들러입니다. – user1018513

관련 문제