Also, ich habe zwei Threads.
Thread man verwaltet die Clientverbindungen. (Es gibt nur einen Client und einen Server) Ich nenne es meinen Server-Thread.
Thread two verwaltet das Senden von Nachrichten an den Client. Ich nenne es meinen Nachrichtenprozessor-Thread.
Thread eins ist verantwortlich, unter anderem regelmäßig einen Heartbeat an den Client zu senden.
Beim Programmieren nahm ich an, dass die Sockets nicht Thread-sicher 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 habe auch angenommen, dass der "PrintWriter" analog zum Socket-Puffer in Java ist.
Unter diesen Annahmen habe ich diese Funktion geschrieben, um einen Herzschlag zu senden:
%Vor%Der andere Thread, der "Prozessor", macht etwas Ähnliches, indem es:
%Vor%Auf diese Weise würde ich jedes Mal einen neuen "Puffer" erstellen, wenn ich einen Herzschlag senden wollte, und meine Nachrichten würden niemals überschrieben.
Leider scheint das nicht der Fall zu sein. Und ich bekomme eine Nachricht wie folgt durch die Leitung: dsgdsbHEARTBEAT # sdg
Dies verursacht später einen Core-Dump.
Hier sind meine Fragen:
1) Sockets sind natürlich nicht threadsicher, aber sind die PrintWriter, die ich von ihnen bekomme, threadsicher? Oder gibt es nur den gleichen PrintWriter zurück?
2) Was ist analog zum Socket-Buffer 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?
Es ist ein schlechtes Design, diese multiplen PrintWriter
s im selben Stream zu haben. Wirklich wollen Sie mindestens das Objekt, das sie ruft, synchronisiert werden (oder Thread beschränkt).
Nehmen wir jedoch an, Sie möchten mehrere PrintWriter
s:
Erstes Problem: Writer
s benutzt this
nicht als Sperre. PrintWriter
und BufferedWriter
verwenden standardmäßig Writer
, mit denen sie als Sperre konstruiert sind. Dies ist offensichtlich vollständig gebrochen. Sie sollten die Writer
-Sperre verwenden, nicht die Writer
selbst. Ein einfacher Fehler, da das Sperren eines Features von Object
die Sicherheit des statischen Typs beseitigt. Sie müssen also ein PrintWriter
mit dem Socket OutputStream
(oder einem anderen gemeinsamen Objekt) als Sperre konstruieren.
Zweitens haben wir eine Pufferung innerhalb von PrintWriter
. So kommt das Ende eines Puffers, die Hälfte wird geschrieben und die Hälfte wartet auf den nächsten Schreibvorgang. Um dies zu verhindern, sperren Sie entweder eine print
und flush
extern oder verwenden Sie die automatische Spülung und fügen Sie ein neues Zeilenzeichen hinzu.
Es ist also nicht sinnvoll threadsicher, aber Sie können es hacken. Oder Sie können ein besseres Design verwenden.
Sie brauchen eine Möglichkeit, dieselbe PrintWriter
zwischen den Threads zu verwenden ( t1.writer == t2.writer
, nicht nur PrintWriter
s, die aus derselben OutputStream
erstellt wurden). Mit dem gleichen PrintWriter
werden alle Schreibvorgänge synchronisiert.
Tags und Links java multithreading sockets