2016-03-23 6 views
0

Ich arbeite an einer Java-Client/Server-Anwendung mit einer ziemlich spezifischen Reihe von Regeln, wie ich sie entwickeln muss. Der Server erstellt eine Instanz mit Eingabe- und Ausgabeströmen für den Client-Socket, und jede Eingabe und Ausgabe zwischen ihnen wird durch Ereignisse in der Client-GUI ausgelöst.Java - Können zwei Threads auf der Clientseite den gleichen Eingabestream vom Server verwenden?

Ich habe jetzt in der Funktionalität serverseitig hinzugefügt, die periodische Updates an alle angeschlossenen Clients senden wird (durch Speichern jedes erstellten PrintWriter Objekts aus ClientHandlers in einem ArrayList<PrintWriter>). Ich brauche einen äquivalenten Mechanismus clientseitig, um diese Nachrichten zu verarbeiten, und mir wurde gesagt, dass dies in einem zweiten clientseitigen Thread geschehen muss, dessen run()-Methode eine do...while(true)-Schleife verwendet, bis der Client die Verbindung trennt.

Das alles macht für mich bisher Sinn, mit dem ich kämpfe ist die Tatsache, dass die beiden Threads den einen Eingabestream teilen müssen, und im Wesentlichen "ignorieren" alle Nachrichten, die nicht von dem Typ sind Griff. In meinem Kopf, sollte es in etwa so aussehen:

Unter der Annahme, dass jede Nachricht vom Server ein boolean Wert true auf einer Nachricht zu allen, und einem Wert false auf einer Nachricht an einen einzelnen Client sendet ...

Existing Client Thread 
//method called from actionPerformed(ActionEvent e) 
//handles server response to bid request 
public void receiveResponse() 
{ 
    //thread should only process to-specific-client messages 
    if (networkInput.nextBoolean() == false) 
    { 
     //process server response... 
    } 
} 


Second Client-side Thread 
//should handle all messages set to all clients 
run() 
{ 
    do { 
     if (networkInput.nextBoolean() == true) 
     { 
      //process broadcasted message... 
     } while (true); 
} 

Als sie brauchen die gleichen Eingangsstrom zu verwenden, würde ich natürlich wait/notify Anrufe einige synchronized, das Hinzufügen, aber im allgemeinen ist, was ich suche hier möglich zu tun? Oder werden die zwei Threads, die versuchen, aus dem gleichen Eingabestrom zu lesen, sich gegenseitig zu sehr stören?

Bitte lassen Sie mich wissen, was Sie denken!

Danke, Mark

+0

'InputStream' ist nicht threadsicher; wenn möglich mit Synchronisierung würde ich versuchen, es zu vermeiden. –

+0

Es ist initialisiert als 'Scanner (socket.getInputStream())', ist das genauso schlimm? Ich liebe nicht die Art, wie es strukturiert ist, aber ich kann es nicht anders sehen, da mir gesagt wurde, dass die clientseitige Verarbeitung in zwei separaten Threads erfolgen muss. Irgendwelche Alternativen, von denen ich weiß, dass ich vermisse? @ElliottFrisch – marcuthh

+1

Ein Stream muss von einem einzelnen Thread gelesen werden, es sei denn, Sie können das Ziel bestimmen, bevor Sie diesen Booleschen Wert gelesen haben, was eindeutig nicht der Spezifikation entspricht. - Benutze einen Thread um den Stream zu lesen und ... naja Peter hat es runter ... – laune

Antwort

2

Sie können es tun, wenn es richtig zu testen kompliziert sein wird und zu erhalten. Wie viel "zu viel" von dir abhängt. Eine einfachere Lösung besteht darin, dass ein Leser-Thread Nachrichten an die beiden Worker-Threads weitergibt.

ExecutorService thread1 = Executors.newSingleThreadedExecutors(); 
ExecutorService thread2 = Executors.newSingleThreadedExecutors(); 
while(running) { 
    Message message = input.readMessage(); 
    if (message.isTypeOne()) 
     thread1.submit(() -> process(message)); 
    else if (message.isTypeTwo()) 
     thread2.submit(() -> process(message)); 
    else 
     // do something else. 
} 
thread1.shutdown(); 
thread2.shutdown(); 
+0

Hi, habe ich in den letzten Tagen gelesen und ein paar Beispiele gefunden. Ich mag das Aussehen, aber es ist etwas, das ich aufgrund der Einschränkungen und Besonderheiten, die ich vorher erwähnt habe, nicht in diesem Projekt verwenden kann. Gibt es eine Chance, dass Sie ein allgemeines Beispiel auf "kompliziertere" Art und Weise veröffentlichen könnten? Danke – marcuthh

+0

@marcuthh der kompliziertere Weg ist zu lang hier zu posten. Wir haben es in der Chronik-Engine verwendet und selbst mit 70 Jahren IT-Erfahrung zwischen dreien von uns haben wir entschieden, dass wir uns in Zukunft von diesem Schritt abwenden werden. Es ist nur ein Schmerz zu unterstützen. –

+0

Ok, kein Problem, danke für deine Zeit trotzdem! – marcuthh