Also, ich habe zwei Threads.Ist der PrintWriter-Thread eines Java-Sockets sicher?
Thread eins verwaltet die Clientverbindungen. (Es gibt nur einen Client und einen Server)
Ich nenne es meinen Server-Thread.
Thread zwei verwaltet das Senden von Nachrichten an den Client. Ich nenne es meinen Nachrichtenprozessor-Thread.
Thread eins ist verantwortlich, unter anderem regelmäßig einen Herzschlag an den Client zu senden.
Bei der Programmierung nahm ich an, dass die Sockets nicht threadsicher waren, aber die Puffer waren, und solange ich separate Puffer für die Server- und Prozessor-Threads verwendete, würde es mir gut gehen.
Ich machte auch die Annahme, dass der "PrintWriter" analog zum Socket-Puffer in Java war.
Unter diesen Voraussetzungen habe ich diese Funktion einen Herzschlag senden:
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();
}
}
Der andere Thread, der „Prozessor“ man tut etwas ähnlich, dass es funktioniert:
printWriter=new PrintWriter(theServer.getClientSocket().getOutputStream());
Auf diese Weise Ich würde jedes Mal einen neuen "Puffer" erstellen, wenn ich einen Herzschlag senden wollte, und meine Nachrichten würden niemals überschrieben werden.
Leider scheint dies nicht der Fall zu sein. Und ich bekomme eine Nachricht wie folgt durch die Leitung: dsgdsbHEARTBEAT # sdg
Dies verursacht einen Core Dump später.
Hier sind meine Fragen:
1) Sockel sind offensichtlich nicht Thread-sicher, sondern sind die PrintWriters ich von ihnen bekommen Thread sicher? Oder gibt es nur denselben PrintWriter zurück?
2) Was ist analog zum Socket-Puffer in Java? Wie sollte ich über dieses Problem nachdenken?
3) Wie mache ich es so, dass diese Threads nicht in den gleichen Puffer auf dem Socket schreiben?
Ich habe Java SE 1.6.0_31 src dafür angeschaut. 'PrintWriter (Writer out)' ruft schließlich 'protected Writer (Objektsperre)' auf, und dort weist 'Writer' diese 'Sperre' der internen 'Sperre' zu, die in 'Writer' zur Synchronisation verwendet wird. Könnten Sie pl. erkläre, warum du denkst, das Sperren ist hier kaputt? – shrini1000
@ shrini1000 'PrintWriter' ruft' Writer (Objektsperre) 'mit' super (out); '. "Lock" ist also "out", anstatt "out.lock". (Dies ist ein Implementierungsproblem - die Spezifikation scheint zu fehlen.) –
Dies scheint in Java 8 immer noch der Fall zu sein - PrintWriter ruft super (out) auf und lock ist out, statt out.lock. –