Donc, j'ai deux threads.Le thread PrintWriter d'une socket Java est-il sécurisé?
Le thread 1 gère les connexions client. (Il y a seulement un client et un serveur)
Je l'appelle mon thread de serveur.
Le thread 2 gère l'envoi de messages au client. Je l'appelle mon fil de processeur de message. Le thread un est responsable, entre autres d'envoyer un battement de coeur au client périodiquement. Lors de la programmation j'ai supposé que les sockets n'étaient pas thread-safe, mais les tampons étaient, et aussi longtemps que j'utilisais des tampons séparés pour les threads du serveur et du processeur, tout irait bien. J'ai également fait l'hypothèse que le "PrintWriter" était analogue au tampon socket en Java.
Dans ces hypothèses, j'ai écrit cette fonction pour envoyer un battement de coeur:
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'autre fil, celui de « processeur » fait quelque chose de similaire en ce qu'elle fait:
printWriter=new PrintWriter(theServer.getClientSocket().getOutputStream());
De cette manière Je créerais un nouveau "tampon" chaque fois que je souhaiterais envoyer un battement de coeur, et mes messages ne seraient jamais écrasés.
Malheureusement, cela ne semble pas être le cas. Et je reçois un message venant par le tuyau comme ceci: dsgdsbHEARTBEAT # sdg
Cela provoque une décharge de noyau plus tard.
Voici mes questions:
1) Sockets sont thread évidemment pas sûr, mais sont les PrintWriters que je reçois d'eux thread-safe? Ou est-ce juste de retourner le même PrintWriter?
2) Quelle est l'analogie avec le tampon socket de Java? Comment devrais-je penser à ce problème?
3) Comment faire en sorte que ces threads n'écrivent pas dans le même tampon sur le socket?
J'ai jeté un oeil à Java SE 1.6.0_31 src pour cela. 'PrintWriter (Writer out)' appelle finalement 'Writer protégé (Object lock)' et là, 'Writer' assigne ce 'lock' à son 'lock' interne qui est utilisé dans 'Writer' pour la synchronisation. Alors pourriez-vous pl. expliquer pourquoi vous pensez que le verrouillage est cassé ici? – shrini1000
@ shrini1000 'PrintWriter' appelle' Writer (Object lock) 'avec' super (out); '. Donc 'lock' est' out', au lieu de 'out.lock'. (Ceci est un problème d'implémentation - la spécification semble être manquante.) –
Cela semble toujours être le cas dans Java 8 - Les appels PrintWriter super (out) et le verrou est sorti au lieu de out.lock. –