Ich habe dieses Problem in Java. Ich habe eine Server-Klasse namens MyServer und ich möchte einen Thread-Pool implementieren, wo jeder Thread eine Methode von MyServer ausführt, wenn eine Anfrage kommt. Ich habe eine andere Klasse erstellt, die einen Serverpool namens MultiThreadedSocketServer implementiert. Die Klasse ist dies:Konkurenz in einem Thread-Pool in Java
public class MultiThreadedSocketServer {
public void startServer(MyServer s, int localport, int threadPoolSize) {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(threadPoolSize);
Runnable serverTask = new Runnable() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(localport);
System.out.println("Waiting for clients to connect...");
while (true) {
Socket clientSocket = serverSocket.accept();
clientProcessingPool.submit(new ClientTask(clientSocket, s));
}
} catch (IOException e) {
System.err.println("Unable to process client request");
e.printStackTrace();
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
}
}
die Klasse mit dem Namen MultiThreadedSocketServer hat ein Argument Server s benannt, die es in Client-Task-Klasse übergibt, die ein Thread erstellt wird. Die Client-Task-Klasse ist dies:
class ClientTask implements Runnable {
private final Socket clientSocket;
private MyServer s;
public ClientTask(Socket clientSocket, MyServer s) {
this.s = s;
this.clientSocket = clientSocket;
}
@Override
public void run() {
System.out.println("Got a client !");
String inputLine = null;
try {
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// Do whatever required to process the client's request
inputLine = in.readLine();
if (inputLine.equals("Bye")) {
System.out.println("Bye");
System.exit(0);
}
s.handleRequest(inputLine);
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Wie Sie sehen können, wenn eine Anforderung der handle Methode der Klasse MyServer kommt aufgerufen. Ich möchte, dass diese Methode synchron ausgeführt wird, dh immer nur ein Thread, um diese Methode ausführen zu können. Das Hinzufügen von synchronisiert vor der Methodenimplementierung bringt nichts.
Kann jemand mir den richtigen Weg geben, dies zu tun? Vielen Dank im Voraus für Ihre Zeit.
PS: Ich habe den ganzen Code
MyServer Klasse http://pastebin.com/6i2bn5jj
Multithreaded Server-Klasse http://pastebin.com/hzfLJbCS
Wie es in Haupt ersichtlich schaffe ich drei Anfragen mit handle mit Argumenten Aufgabe, task2 und Tschüss.
Das würde eine korrekte Ausgabe
Waiting for clients to connect...
Got a client !
This is an input Task
Request for Task
Got a client !
This is an input task2
Request for task2
Got a client !
This is an input
Bye
werden, sondern ist die Reihenfolge gemischt. Manchmal kann Bye, der den Server schließt, zuerst ausgeführt werden. Ich möchte sicherstellen, dass die Bestellung diejenige ist, in der die Anfragen hauptsächlich erstellt werden.
Wenn 'MyServer.HandleReq() 'synchronisiert wird, verhindert dies, dass mehrere Threads die Methode gleichzeitig ** auf derselben MyServer-Instanz ** aufrufen. Wie viele MyServer-Instanzen haben Sie? Randnotiz: Bitte beachten Sie die Namenskonventionen. –
Nur eine MyServer-Instanz wird immer ausgeführt. Entschuldigung, ich weiß nicht über die Namenskonventionen, wenn Sie klarstellen möchten, dass ich meinen Beitrag bearbeiten werde –
Methoden beginnen mit einem Kleinbuchstaben. HandleReq sollte HandleReq oder besser HandleRequest sein. Gleich für Variablen. ThreadPoolSize sollte threadPoolSize sein. Wenn Sie eine einzelne MyServer-Instanz haben, ist die Synchronisierung der Methode in Ordnung. Wie testen Sie, dass es nicht richtig synchronisiert ist? –