Ich habe eine Feder @RestController
, also eine einfache servlet
.Wie blockiere und entsperren Sie einen Servlet-Thread?
Wenn das Servlet gleichzeitig mit den gleichen Werten aufgerufen wird (Benennung eines "Hash" in diesem Beispiel), möchte ich alle bis auf das erste Servlet blockieren. Und wenn dieser beendet ist, möchte ich die blockierten befreien.
Als eine Lösung dachte ich daran, den Hash zu einem ConcurrentHashMap
hinzuzufügen, und auch die Servlet-Threads zu diesem hashmap als Wert für den Hash-Schlüssel hinzufügen.
Aber wie könnte ich dort einen laufenden Java-Thread hinzufügen?
Der folgende Pseudocode veranschaulicht, was ich versuche zu erreichen:
@RestController
public class MyService {
//a map blocking any concurrent process on the same hash value
private ConcurrentHashMap<String, List<Object>> map;
@RequestMethod
public String myXmlMethod(Param params) {
String hash = params.getHash(); ////assume a value identifying a certain form of logic
if (!map.contains(hash)) {
//here no concurrent task is running, so block the hash until removal
map.put(hash, new ArrayList<Object>());
callLongRunningTaskAndWriteToDB();
List<Object> threads = map.get(hash);
map.remove(hash); //free the hash
//interrupt any waiting threads, as the hash completed now
if (threads != null && !threads.isEmpty()) {
for (thread : threads) {
thread.interruptWait();
}
}
} else {
//this way the servlet thread cannot continue until the timout occurs,
//or the servlet thread is canceled by the main thread in the concurrent hashmap
thread = new Thread(this, Timeout.SECONDS(30));
map.get(hash).add(thread);
waitForThreadTimeoutOrInterrupt();
}
}
}
Frage: Aber wie kann ich eigentlich einen Griff des aktuellen „Faden“ des Verfahrens ausgeführt wird? Damit ich es zur Karte hinzufügen und darauf warten und unterbrechen kann?
Ein Spring '@ RestControler' ist kein Servlet. Spring 'DispatcherServlet' ist ein Servlet. – Savior
Naja, zumindest erstellt es ein Servlet, auf das get-Abfragen zugreifen können. Das ist wichtig für diese Frage. – membersound
Sie möchten jedoch nicht Servlet-Handling-Threads blockieren. Verwenden Sie async, um all diese Dinge zu handhaben, wenn Sie müssen. Spring bietet 'DeferredResult' und' Callable' an, um dies zu erreichen. – Savior