Ich habe einen kritischen Prozess, den ich sicherstellen muss zu jeder Zeit kann nicht zwei äquivalente MyObject verarbeitet werden (kann verschiedene Instanzen sein, aber logisch gleich). Der folgende Code demonstriert die Idee:JAVA Synchronisierung mit zufälliger Zeichenfolge
public class MyClass {
public static ConcurrentMap<MyObject, String> concurrentMap = new ConcurrentHashMap<>();
public void process(MyObject myObject) {
String id = UUID.randomUUID().toString();
String existingId = concurrentMap.putIfAbsent(myObject, id);
synchronized (id) {
if (existingId == null) { // no others, start working right away
// do work
} else { // an equivalent myObject is under processing, wait on it
synchronized (existingId) {
// finally can start doing work
}
}
}
}
}
Der obige Code funktioniert mit Hilfe von synchronized
auf einer zufälligen Zeichenfolge. Aber die Probleme mit diesem Code sind
Jedes Mal, es einen neuen Zufall-ID erzeugt wird, aber nicht verwendet, wenn eine bestehende ID zu einem äquivalenten MyObject in Verbindung gebracht wurde. Der einzige Zweck einer solchen ID besteht darin, als eine einzigartige Sperre zu agieren, die von dem anderen Thread entdeckt werden soll. Denken Sie daran, dass dies durch ein tatsächliches Sperrobjekt ersetzt werden kann?
Es gibt keine Möglichkeit in diesem Code zu wissen, wann MyObject aus der concurrentMap entfernt werden sollte, obwohl dies das Ergebnis nicht beeinflusst. Wenn die concurrentMap wächst, ist das möglicherweise nicht gut. Denken Sie daran, dass hier so etwas wie eine Ladentheke verwendet werden kann?
Danke
Es tut. Die ID wird in der Map gespeichert und von einem anderen Thread extrahiert (wird zu existingId) – user1589188
OK, ich sehe deine Punkte. Ich werde den Kommentar niederschreiben. – markspace