2016-05-04 7 views
2

Ich verwende newFixedThreadPool, um eingehende Anforderungen gleichzeitig an einen Server-Socket zu senden. Aus irgendeinem Grund werden die Arbeiterklassen, die die Clients bedienen, nicht in separaten Threads ausgeführt. Wenn ich mehrere Anfragen an den Socket sende, werden die Anfragen der Reihe nach und nicht gleichzeitig wie gewünscht geliefert. Ich führe OpenJDK 1.8.0_77, wenn das einen Unterschied macht.Executorservice-Worker werden nicht in separaten Threads ausgeführt.

Dies ist ein Auszug meiner Hauptklasse:

ExecutorService executorService = Executors.newFixedThreadPool(100); 
    ServerSocket serverSocket = new ServerSocket(5656); 

    while(true) { 
     Socket socket = serverSocket.accept(); 
     executorService.execute(new ConnectionHandler(socket)); 
    } 

Diese meine Arbeiter-Klasse ist:

public class ConnectionHandler implements Runnable { 

    private Socket socket; 

    public ConnectionHandler(Socket socket) { 
     this.socket = socket; 
    } 

    public void run() { 

     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e1) { 
      e1.printStackTrace(); 
     } 

     BufferedReader reader = null; 
     PrintWriter writer = null; 
     try { 
     reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     writer = new PrintWriter(socket.getOutputStream(), true); 

     while(true) { 
      String line = reader.readLine(); 
      if(line == null) break; 
      writer.println("Echo: " + line); 
     } 
     } catch (IOException e) { 
     throw new RuntimeException(e); 
     } finally { 
     try { 
      if(reader != null) reader.close(); 
      if(writer != null) writer.close(); 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } 
     } 
    } 

    } 
+1

Woher wissen Sie, dass es nicht verschiedene Threads verwendet? Protokollieren Sie den Thread-Namen, um sicher zu sein. –

+1

Sind Sie sicher, dass dies kein Problem Ihres Testclients ist? – mtraut

Antwort

0

Das Problem dieser Aufruf ist:

executorService.execute(new ConnectionHandler(socket)); 

Die execute Methode ist erlaubt, den aufrufenden Thread zu blockieren, bis die Aufgabe abgeschlossen ist, oder sogar den aufrufenden Thread pero hat rm die eigentliche Arbeit. Stattdessen tun Sie dies:

executorService.submit(new ConnectionHandler(socket)); 

Dies wird asynchron ausführen Ihre Aufgabe mit Threads im Pool.

+0

Ich habe es schwer, das zu glauben. Der Beispielcode in der API-Dokumentation für ExecutorService verwendet execute. –

+0

Lesen Sie das Javadoc hier - es besagt, dass der aufrufende Thread verwendet werden kann, um die Arbeit auszuführen: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html#execute % 28java.lang.Runnable% 29 – CodeBlind

+0

@NathanHughes hat Recht - die beiden Methoden unterscheiden sich nur in der Signatur, nicht in ihrem Verhalten bezüglich Threading. Ein Executor, der mit "newFixedThreadPool" erstellt wurde, verteilt Aufgaben an verschiedene Threads. – mtraut

1

Tut mir leid, ich bin nicht gut mit dem Computer.

Das Problem war, dass ich viele Nachrichten in einer Schleife zum Socket echo, aber der Echo-Befehl sendet Nachrichten sequenziell und wartet auf jede Nachricht zu beenden, bevor es die nächste sendet.

Verwandte Themen