Synchronisation in Threads für Java
-
05-07-2019 - |
Frage
Ich habe einen home grown Webserver in meiner app. Dieser Web-Server startet einen neuen Thread für jede Anforderung, die in die Steckdose kommt in Kauf genommen werden. Ich mag, dass der Web-Server warten, bis ein bestimmte Punkt im Thread getroffen wird gerade erstellt.
Ich habe auf dieser Seite und Beispiele auf dem Netz durch viele Beiträge, aber kann nicht den Web-Server erhalten, um fortzufahren, nachdem ich den Faden sagen zu warten. Ein Basiscodebeispiel wäre toll.
Ist das Schlüsselwort synchronized der richtige Weg, um dies zu realisieren? Wenn ja, wie kann dies erreicht werden? Code-Beispiele sind unter meiner App:
Web Server
while (true) {
//block here until a connection request is made
socket = server_socket.accept();
try {
//create a new HTTPRequest object for every file request
HttpRequest request = new HttpRequest(socket, this);
//create a new thread for each request
Thread thread = new Thread(request);
//run the thread and have it return after complete
thread.run();
///////////////////////////////
wait here until notifed to proceed
///////////////////////////////
} catch (Exception e) {
e.printStackTrace(logFile);
}
}
Themen-Code
public void run() {
//code here
//notify web server to continue here
}
Update - Abschlusscode ist als unten. Die HttpRequest
ruft nur resumeListener.resume()
wenn ich einen Antwort-Header senden (natürlich auch die Schnittstelle als eine separate Klasse hinzufügen und die addResumeListener(ResumeListener r1)
Methode in HttpRequest
):
Web Server-Teil
// server infinite loop
while (true) {
//block here until a connection request is made
socket = server_socket.accept();
try {
final Object locker = new Object();
//create a new HTTPRequest object for every file request
HttpRequest request = new HttpRequest(socket, this);
request.addResumeListener(new ResumeListener() {
public void resume() {
//get control of the lock and release the server
synchronized(locker) {
locker.notify();
}
}
});
synchronized(locker) {
//create a new thread for each request
Thread thread = new Thread(request);
//run the thread and have it return after complete
thread.start();
//tell this thread to wait until HttpRequest releases
//the server
locker.wait();
}
} catch (Exception e) {
e.printStackTrace(Session.logFile);
}
}
Lösung
Zu allererst Echo ich das Gefühl von anderen, die hier das Rad neu zu erfinden, höchstwahrscheinlich zu einer Vielzahl von Fragen für Sie. Allerdings, wenn Sie wollen auf jeden Fall diesen Weg zu gehen, was Sie versuchen zu tun ist, nicht schwer. Haben Sie experimentierten mit Jetty?
Vielleicht so etwas wie folgt aus:
public class MyWebServer {
public void foo() throws IOException {
while (true) {
//block here until a connection request is made
ServerSocket socket = new ServerSocket();
try {
final Object locker = new Object();
//create a new HTTPRequest object for every file request
MyRequest request = new MyRequest(socket);
request.addResumeListener(new ResumeListener() {
public void resume() {
locker.notify();
}
});
synchronized(locker){
//create a new thread for each request
Thread thread = new Thread(request);
//start() the thread - not run()
thread.start();
//this thread will block until the MyRequest run method calls resume
locker.wait();
}
} catch (Exception e) {
}
}
}
}
public interface ResumeListener {
public void resume();
}
public class MyRequest implements Runnable{
private ResumeListener resumeListener;
public MyRequest(ServerSocket socket) {
}
public void run() {
// do something
resumeListener.resume(); //notify server to continue accepting next request
}
public void addResumeListener(ResumeListener rl) {
this.resumeListener = rl;
}
}
Andere Tipps
Sie können mit java.util.concurrent .CountDownLatch mit einer Zählung von 1 für diese . Vereinbaren Sie für eine Instanz davon durch den übergeordneten und untergeordneten Thread erstellt und freigegeben wird (beispielsweise schafft es in HttpRequest
Konstruktor, und von einer Elementfunktion abrufbare). Der Server ruft dann await()
auf, und der Faden trifft countDown()
, wenn es bereit ist, seine Eltern zu lösen.
Sie müssen wahrscheinlich ein Java Zustand . Aus der Dokumentation:
Bedingungen (auch als Bedingung bekannt Warteschlangen oder Zustandsgrößen) bereitzustellen ein Mittel für einen Thread zu suspendieren Ausführung (auf „wait“), bis gemeldet von einem anderen Thread, der einige Zustand Bedingung kann jetzt wahr sein.
Ausführen unter einem Debugger und einen Haltepunkt setzen?
Wenn nicht machbar, dann eine Linie von System.in lesen?