Ich frage mich, ob eine typische while(true)
ServerSocket-Abhörschleife einen ganzen Kern braucht, um zu warten und eine Clientverbindung zu akzeptieren (selbst wenn man runnable implementiert und Thread .start()
verwendet)
Ich implementiere eine Art verteilter Computercluster und jeder Computer benötigt jeden Kern, den er zur Berechnung hat. Ein Master-Knoten muss mit diesen Computern kommunizieren (wobei statische Methoden aufgerufen werden, die die Funktionsweise des Algorithmus ändern).
Der Grund, warum ich Sockets verwenden muss, liegt an den plattformübergreifenden / sprachübergreifenden Fähigkeiten. In einigen Fällen wird PHP diese statischen Java-Methoden aufrufen.
Ich habe einen Java-Profiler (YourKit) benutzt und kann meinen laufenden ServerSocket-Listen-Thread sehen, der niemals schläft und immer läuft. Gibt es einen besseren Ansatz, um das zu tun, was ich will? Oder wird der Performance-Hit vernachlässigbar sein?
Bitte zögern Sie nicht, einen Vorschlag zu machen, wenn Sie sich einen besseren Weg vorstellen können (Ich habe RMI ausprobiert, aber es wird nicht in mehreren Sprachen unterstützt.
Danke allen
Wenn Sie so etwas meinen:
%Vor% Dann, nein, der Aufruf von accept()
"nimmt keinen ganzen Kern". Es ist ein blockierender Aufruf, der es ermöglicht, die CPU für einen anderen Thread zu terminieren, bis ein Client tatsächlich eine Verbindung herstellt. Sobald der Aufruf von accept()
zurückkehrt, wird der aktuelle Thread für die Ausführung geplant und verbraucht CPU, bis er in der nächsten Iteration der Schleife auf accept()
blockiert.
Um zu verhindern, dass der Listenrückstau anderer Clients zu groß wird, behandelt ein anderer Thread normalerweise die Interaktion mit dem neu akzeptierten Socket
, sodass ein Thread sich auf das Akzeptieren neuer Clients konzentriert. Der Socket-Handlingthread kann mit NIO viele Sockets verarbeiten, oder er kann für einen einzelnen Socket bestimmt sein, der viel einfacher zu programmieren ist, aber nicht über viele hundert gleichzeitige Verbindungen skalieren kann.
Vielleicht möchten Sie sich die Java 1.4 nio-Bibliotheken und insbesondere ServerSocketChannel ansehen. Ich benutze dies sehr erfolgreich, um einen effizienten Server zu implementieren, die wichtigsten Bits des Codes sind:
%Vor%Und der Listener ist nur eine Schleife, die läuft:
%Vor%Ich habe einen Java-Profiler (YourKit) benutzt und ich kann meinen laufenden ServerSocket-Abhör-Thread sehen und er schläft nie und läuft immer.
Grundsätzlich führt der Profiler Sie in die Irre.
Ich gehe davon aus, dass Ihr Code so aussieht:
%Vor% Dies wird keine wesentliche CPU verbrauchen ... es sei denn, Sie haben etwas pathologisches getan, wie den Aufruf von ServerSocket.setSoTimeout(int)
mit einem kleinen Timeout.
Lass den Kern ein wenig schlafen. Fügen Sie in Ihrer Runnable-Methode etwas wie
hinzu %Vor%in jeder Schleife.
Das sollte die CPU-Auslastung erheblich reduzieren
Edit: schlechte Idee, siehe Kommentare, sorry, meine Schuld
Und: verwende nicht während (wahr). Es ist ein schreckliches Design, wie die Semantik nahelegt, dass das Wahre irgendwann nicht mehr wahr sein wird. Normalerweise möchten Sie eine flüchtige oder atomare Variable aus dem Hauptthread abfragen
%Vor%Auf diese Weise hat der Haupt-Thread die Möglichkeit, den Listener-Thread zu stoppen.
Tags und Links java multithreading sockets performance core