Quindi, ho due thread.Il thread PrintWriter di un socket Java è sicuro?
Il primo thread gestisce le connessioni client. (C'è solo un client e un server)
Io lo chiamo thread del mio server.
Il thread due gestisce l'invio di messaggi al client. Lo chiamo thread del mio processore di messaggi.
Il thread uno è responsabile, tra l'altro, di inviare periodicamente un heartbeat al client.
Durante la programmazione ho ipotizzato che i socket non fossero thread-safe, ma i buffer lo erano, e fintanto che usavo buffer separati per i thread del server e del processore, andava bene.
Ho anche ipotizzato che "PrintWriter" fosse analogo al buffer di socket in Java.
Sotto queste ipotesi ho scritto questa funzione per inviare un battito cardiaco:
public void sendHeartBeat(){
logger.info("Sending a hearbeat!");
PrintWriter printWriter=null;
try {
printWriter = new PrintWriter(clientSocket.getOutputStream());
} catch (IOException e) {
logger.info(e.toString());
}
if(printWriter!=null){
printWriter.print("HEARTBEAT#");
printWriter.flush();
}
}
L'altro filo, quello "processor" fa qualcosa di simile a quello che fa:
printWriter=new PrintWriter(theServer.getClientSocket().getOutputStream());
In questo modo Creerei un nuovo "buffer" ogni volta che volevo inviare un heartbeat e i miei messaggi non sarebbero mai stati sovrascritti.
Sfortunatamente questo non sembra essere il caso. E ricevo un messaggio proveniente dalla pipe in questo modo: dsgdsbHEARTBEAT # sdg
Ciò causa un core dump in seguito.
Ecco le mie domande:
1) prese sono, ovviamente, non thread-safe, ma sono le PrintWriters che ricevo da loro thread-safe? O sta solo restituendo lo stesso PrintWriter?
2) Che cosa è analogo al buffer di socket in Java? Come dovrei pensare a questo problema?
3) Come faccio a fare in modo che questi thread non scrivano sullo stesso buffer sul socket?
Ho dato un'occhiata a Java SE 1.6.0_31 src per questo. 'PrintWriter (Writer out)' in definitiva chiama 'Writer protetto (Object lock)' e lì 'Writer' assegna questo 'lock' al suo 'lock' interno che viene usato in 'Writer' per la sincronizzazione. Quindi potresti pl. spiega perché pensi che il blocco sia rotto qui? – shrini1000
@ shrini1000 'PrintWriter' chiama' Writer (Object lock) 'con' super (out); '. Quindi 'lock' è' out', invece di 'out.lock'. (Questo è un problema di implementazione - la specifica sembra essere mancante.) –
Questo sembra essere ancora il caso in Java 8 - PrintWriter chiama super (out) e lock è fuori invece di out.lock. –